Sorry it took me a while to reply...

On Tue, Sep 3, 2013 at 5:39 PM, Lukas Eder <[email protected]> wrote:

> Hi Daniel,
>
> You have some interesting ideas, there...
>
> 2013/9/3 Daniel Danilatos <[email protected]>
>
>> Thanks Lukas
>>
>>
>> On Tue, Sep 3, 2013 at 1:39 AM, Lukas Eder <[email protected]> wrote:
>>
>>>
>>> 2013/9/2 Dan <[email protected]>
>>>
>>>> It would be great if it were easy to have a Record implementation that
>>>> delegated to another, especially for the generated record classes.
>>>>
>>>> Example use case 1: I have a record that maps to a few rows joined
>>>> together from 2-3 tables. I can set fields on it using the (verbose)
>>>> non-typesafe methods, but it would be great to use generated setFoo(),
>>>> setBar(), etc methods. I can't go record.into(FirstTable.class).setFoo()
>>>> because that creates a copy - it would be great if I could easily go
>>>> FirstTable.wrap(record).setFoo(x) and have that setFoo() method delegate to
>>>> the underlying wrapped record, SecondTable.wrap(record).setBar(y) affects
>>>> the same record, and so on.
>>>>
>>>
>>> Yes, these kinds of one-to-one relations would often be useful if known
>>> to jOOQ. There had been quite a few discussions around this subject in the
>>> recent past. Currently, jOOQ does not add such cleverness to records.
>>> However, if your join product is guaranteed to be "updatable", why not just
>>> create a database view and make these things transparent to jOOQ?
>>>
>>
>> I remember looking into creating a view and realising mysql couldn't
>> handle insert/update/delete fully properly.
>>
>
> True, MySQL has some harder restrictions there, compared to Oracle, for
> instance.
>
>
>> Currently I am porting code from a PHP ORM into JOOQ so looking to get
>> things up and running - doesn't necessarily have to be done in the same
>> fashion. In the old code base, one could represent "inheritance" by having
>> table B join to table A in a 1:1 relationship (they shared primary keys)
>> and that would be abstracted away (very similar to a view).
>>
>
> Interesting. What ORM is this? Maybe I can study how they implemented this
> inheritance notion. There are generally three ways of implementing
> inheritance in relational models. One has to be careful not to map such a
> model too strictly to a Java domain, as the two domains will remain
> independent.
>

An ORM I wrote ages ago before ORM was a TLA :)  You probably don't want to
study what I did.


>
> Nonetheless, I think that supporting "inheritance" modelled as a set of
> 1:1 relationships with some sort of discriminator might be a good thing to
> implement in jOOQ. Obviously, such an implementation should be somewhat
> compatible with JPA, to follow the principle of least astonishment.
>

If jOOQ provides the right set of primitives, there should be no need to
bake in this feature, as it would be easily implementable on top.  I know
I'm oversimplifying, and I don't have all the hundreds of use cases in mind
that you need to juggle, but as a simple example:  say the generated record
classes did not fit into a large inheritance hierarchy, but instead
subclassed a very simple delegating base class (merely to take care of most
of the boilerplate) and then were implemented by receiving an inner record
in their constructor. The actual code would be very similar - the setFoo
and getBar methods would still delegate to setValue & getValue, except on
an inner object, instead of their parent class. Except now I can provide
any other backing record of my choosing in the constructor, and reuse all
this conveniently generated code. For example, I can pass in a record that
is the result of a join query, to get a certain view of it, read values
with nice getters, make changes with nice setters, etc.


>
> I guess a related question is this: Is there a simple way to implement the
>> Record interface? E.g. where one could override key methods such as
>> getValue(field) and have the rest work correctly. (The full interface is
>> huge) If I could even just construct a record with a list of Fields that
>> might be enough for my purposes, but any constructors that work that way
>> are all package private on on package private classes.
>>
>
> Currently, no, there is no simple way to do this. I can see two possible
> method additions, though:
>
> - Record DSLContext.newRecord(Field<?>...)
> - <T1> Record1<T1> DSLContext.newRecord(Row1<T1>)
> - <T1, T2> Record2<T1, T2> DSLContext.newRecord(Row2<T1, T2>)
> - <T1, T2, ..., T[N]> Record2<T1, T2, ..., T[N]>
> DSLContext.newRecord(Row[N]<T1, T2, ..., T[N]>)
>
> I will register a feature request for this change #2722:
> https://github.com/jOOQ/jOOQ/issues/2722
>
> Obviously, this would be yet another way to copy record data into a new
> record type. Maybe, some more useful API could be added to jOOQ to cover
> other parts of your use-case?
>
> Note that another, related feature is already on the roadmap:
> https://github.com/jOOQ/jOOQ/issues/1838
>
>  Example use case 2: Disambiguate fields. If I go dsl.select()... with
>>>> some joins, and the table field names clash, jooq / sql will not complain
>>>> because when generating the SQL jooq disambiguates the field names with
>>>> tables. However in the returned records, it seems that table names are
>>>> ignored and whatever fields came last clobber earlier fields (usually one
>>>> would prefer the other way round, but that's not 100% of the time either).
>>>>
>>>
>>> That shouldn't be the case. If you have an exact match of table name /
>>> field name, you should get the right value, even if field names clash. Can
>>> you provide a test case to reproduce the issue?
>>>
>>
>> I'll try to reproduce this again and make sure I wasn't doing something
>> wrong. This observation is unrelated to what I'm trying to do above.
>>
>
> OK, thanks
>
>  Being able to get a specific "view" of the record would again be very
>>>> helpful, e.g.  FooTable.wrap(record).getId() vs
>>>> BarTable.wrap(record).getId(). Of course that doesn't disambiguate the case
>>>> of table aliasing but that should be easily handled with modest extensions
>>>> to this concept.  I think this would be more convenient than being forced
>>>> to explicitly list all the fields to select() and aliasing the clashing
>>>> ones.
>>>>
>>>
>>> There's
>>> http://www.jooq.org/javadoc/latest/org/jooq/Record.html#into(org.jooq.Table),
>>> instead of Table.wrap(Record). Does this help?
>>>
>>
>> As far as I can tell that creates copies of the source record, not views.
>>
>
> True. Currently, there is no easy way to create views of records, short of
> implementing Record. I had recently thought about this myself in the
> context of Result.intoGroups(). This method performs grouping of a Result
> by several group fields. The group key is a Record "copy", not a Record
> "view". Making this a view, however, would be quite complicated.
>
> Anyway, most of jOOQ's API operates on copies, where the semantics of
> subsequent CRUD operations may be a bit surprising / annoying. E.g. if
> copying a record, a subsequent store() performs an INSERT in jOOQ, not an
> UPDATE. With views, the operations would remain the same.
>


Heh, actually, this caused a moment of confusion the first time I did this,
when I thought I was going to get an update but instead got an insert
because of the copy. I think either way is fine though, as long as the
documentation is clear.


>
> I'll have to give this some more thought. I have registered #2721 for this:
> https://github.com/jOOQ/jOOQ/issues/2721
>
> Cheers
> Lukas
>
> --
> You received this message because you are subscribed to the Google Groups
> "jOOQ User Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to