Nicolai,
2018-05-08 11:18 GMT+02:00 Nicolai Ehemann <[email protected]>:
> Hi,
>
> sorry, I posted my messages through google groups where the original
> context is still visible; I suspect you do not, so here is the original
> requirement:
>
I do have the context, but it is 2 years old and usually, that just means
that it is out of date :) So I generally prefer asking for an updated
context rather than reverse engineering things that might no longer be true.
Thanks for summarising it again for me.
> I have two tables aggregated by a foreign key. Sometimes I just need table
> A, sometimes I want the corresponding record from table B to be filled in a
> member variable. So my SELECTs are like
> create.select().from(A).where(...)
> or
> create.select().from(A).leftJoin(B).on(A.B_ID.eq(B.B_ID))
>
> Now, I want the RecordMapper to decide wether to fill a member of object A
> with an object B created from the record based on the existance of B.B_ID
> in the record. I solved this with your suggestion of:
>
> if (B.B_ID.equals(record.field(B.B_ID))) { ... }
>
> The field() method call produces ambiguity warnings (although they are in
> place to prevent ambiguity),
> and while will already not be obvious to others what that condition is
> intended to do, with https://github.com/jOOQ/jOOQ/issues/4477 there will
> also be an exceptin thrown and the code will get even more complicated.
>
The fact that this particular call produces a warning is either a bug, or
your example might be incomplete. In your particular example, there is no
ambiguity as both B_ID columns are fully qualified in the query, and you're
retrieving the fully qualified column with your call, so there should be no
warning. Let's look at code:
https://github.com/jOOQ/jOOQ/blob/version-3.10.7/jOOQ/src/main/java/org/jooq/impl/Fields.java#L86
public final <T> Field<T> field(Field<T> field) {
if (field == null)
return null;
// [#4540] Try finding a match by identity
for (Field<?> f : fields)
if (f == field)
return (Field<T>) f;
// [#1802] Try finding an exact match (e.g. exact matching qualified
name)
for (Field<?> f : fields)
if (f.equals(field))
return (Field<T>) f;
...
One of these two loops should return B.B_ID from the record.field() call,
so the warning (further down in the code) shouldn't be issued.
> So the question is, is there a better way to do this, and/or would it be
> sensible to get an api for this
>
I don't see the value of additional API at this point. The logic you
mentioned is still reasonable but either the example was incomplete, or
there is a subtle bug. An alternative would be to take all columns, put
them in a list, and call contains on it:
Arrays.asList(record.fields()).contains(B.B_ID)
This will definitely work around any potential ambiguity issues and focus
only on calling equals() on each field in the record.
Alternatively, to avoid this issue, you could somehow remember how you
produced the result, and use a RecordMapper in function of that. I'm
assuming you want a single RecordMapper that can handle all the mappings,
but perhaps it might be easier to pick a dedicated RecordMapper for each
query. After all, how would your mapper distinguish between LEFT / RIGHT /
FULL / INNER JOIN between A and B, or projections that do not select all
the columns, or any similar "special case" on a per-query basis?
(I could of course add this to our JooqUtils class which is atm very small,
> fortunately ;-))
>
Good to know :)
--
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/d/optout.