1

I have to access the same table for multiple references from a "root" table. In order to do so, I'm creating aliases for these tables:

protected final Table<XyzRecord> foo = Tables.XYZ.as("foo", <foo-alias-function>);
protected final Table<XyzRecord> bar = Tables.XYZ.as("bar", <bar-alias-function>);

bar-alias-function would be declared as follows_

protected final Function<Field<?>, String> fooFieldAliasFunction = f -> "foo_" + f.getName();

Now since I'd like to benefit from type safe queries, I need to re-use the same alias-function in my queries to access the fields:

jooq.select()
  .from    (root)
  .leftJoin(foo).on(
         checklistTarget.field(fooFieldAliasFunction.apply(Tables.XYZ.ID), Tables.XYZ.ID.getType())
     .eq(root.FOO_ID)
   )
  .leftJoin(bar).on(
         checklistTarget.field(barFieldAliasFunction.apply(Tables.XYZ.ID), Tables.XYZ.ID.getType())
     .eq(root.BAR_ID)
   )
   ...
;

This seems awefully clumsy (a lot of code) and not terribly efficient (since the aliased field names are probably stored with the aliased table).

I assumed there would be a method on the alias that would give me the aliased field directly (e.g. foo.getField(Tables.XYZ.ID), but that doesn't seem to be the case.

Of course the problem is amplified if I want to select specific fields...

Am I missing something? What's the recommended way of doing this?

Thank you!

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
Chris
  • 312
  • 1
  • 11

1 Answers1

0

I assumed there would be a method on the alias that would give me the aliased field directly (e.g. foo.getField(Tables.XYZ.ID), but that doesn't seem to be the case.

This kind of API would be useful indeed, although the existing Table.field(Field) method shouldn't be retrofitted to assume this behaviour. A new method might be introduced. On the other hand, you could write a simple utility:

<T, R extends Record> Field<T> field(Table<R> table, TableField<R, T> field) {
    if (table == foo)
        return foo.field(fooFieldAliasFunction.apply(field), field.getType());
    else if (table == bar)
        return foo.field(barFieldAliasFunction.apply(field), field.getType());
    else
        throw IllegalArgumentException();
}

And then call it like this:

jooq.select()
    .from    (root)
    .leftJoin(foo).on(field(foo, XYZ.ID).eq(root.FOO_ID))
    .leftJoin(bar).on(field(bar, XYZ.ID).eq(root.BAR_ID))
   ...
;
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • Thank you for your answer. Since I'm generating the code, it's not a huge deal, just thought I probably missed something. Do you think you might be adding such a method to the API, e.g. `Table#aliasedField(Field)` (I realize that internally, this would semantically conflict with `Table#getAliasedTable`, but since that's not API, maybe that could be changed to Table#getWrappedTable`, clarifying things)? – Chris Mar 17 '19 at 19:24
  • @Chris: It's certainly worth thinking about this, but no promises yet: https://github.com/jOOQ/jOOQ/issues/8428 – Lukas Eder Mar 18 '19 at 08:31