Search code examples
javasqljooqwith-clause

JOOQ query to JOIN ON WITH clause


How can I write a JOOQ query to join on a field from a "with" clause?

For example, I've tried:

create.with("a").as(select(
                           val(1).as("x"),
                           val("a").as("y")
                   ))
      .select()
      .from(tableByName("a")
      .join(ANOTHER_TABLE)
          .on(ANOTHER_TABLE.ID.eq(tableByName("a").field("x")))
      .fetch();

However, as the compiler doesn't know the type of tableByName("a").field("x") it cannot resolve which eq() method to use. Given that I know the type, is there a way I can provide it explicitly? Or is there another approach I should take to join on a field from a "with" clause?


Solution

  • While I certainly agree with flutter's answer being a more desireable path to a solution here, I'll just quickly add a response that answers your specific compilation error question.

    There are three things that are wrong with your current join predicate:

    ANOTHER_TABLE.ID.eq(tableByName("a").field("x"))
    
    1. DSL.tableByName() is deprecated. It is generally recommended to use table(Name) instead.
    2. Such a dynamically constructed Table does not know of any of its field() references, thus table(name("a")).field("x") will return null
    3. The compilation error is due to your ID reference being of type Field<Integer> (probably), and thus the Field.eq() method expects a Field<Integer> argument as well. Without any knowledge about the type of your field "x", the jOOQ API / Java compiler infers Field<Object>, which is invalid.

    So, the solution would be to write:

    // field(Name, Class)
    ANOTHER_TABLE.ID.eq(field(name("a", "x"), Integer.class))
    
    // field(Name, DataType)
    ANOTHER_TABLE.ID.eq(field(name("a", "x"), ANOTHER_TABLE.ID.getDataType()))
    

    I.e. to use DSL.field(Name, Class<T>), or DSL.field(Name, DataType<T>) if you're using custom data type bindings / converters.