Vijay Parashar
Vijay Parashar

Reputation: 50

How to build Insert into with select statement that uses constant values using JOOQ Query Builder

I have an insert statement that is inserting some constant values and it needs to select some reference keys from other tables by lookup. The query looks something like this.

Insert into repository.buffer (
    b_external_id,
    b_buffer_type_id,
    b_entrypoints,
    b_site_id,
    b_state,
    b_uri)
select '100A',bt_id,'["/locations/100A"]'::jsonb,s_id,'ready','/buffers/100A'
from  repository.site, repository.buffer_type
where s_name = 'bar'
and bt_external_id = 'FOO';

My JOOQ Query Builder code looks like this

dslContext
            .insertInto(
                table("repository.buffer"),
                field("b_external_id"),
                field("b_buffer_type_id"),
                field("b_entrypoints"),
                field("b_site_id"),
                field("b_state"),
                field("b_uri"))
            .select(select(
                    inline(null, String.class),
                    field("bt_id"),
                    inline(null, Object.class),
                    field("s_id"),
                    inline(null, String.class),
                    inline(null, String.class))
                    .from(table("repository.site"), table("repository.buffer_type"))
                    .where(field("s_name").eq(cast(null, String.class)))
                    .and(field("bt_external_id").eq(cast(null, Integer.class))))
                .onConflict().doNothing()
            .getSQL();

This statement fails to compile with following error

Error:(98, 25) java: incompatible types: org.jooq.SelectConditionStep<org.jooq.Record6<java.lang.String,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.String,java.lang.String>> cannot be converted to org.jooq.Select<? extends org.jooq.Record6<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object>>

Somehow as soon as I use inline in the select return type of select changes to SelectConditionStep instead of Select.

Any clue to solve this?

Upvotes: 0

Views: 1703

Answers (1)

Lukas Eder
Lukas Eder

Reputation: 220842

The fact that the compiler infers SelectConditionStep is irrelevant here, as it is a subtype of Select, and as such, totally acceptable for the INSERT .. SELECT statement. The problem is that when using plain SQL in your insertInto() clause and not providing any column data types, the compiler will infer Object for each individual column, instead of String.

Remember that jOOQ is a very strongly typed API and this mostly helps you get your SQL right. In your particular case, make sure you will specify a data type on each column reference:

dslContext
    .insertInto(
        table("repository.buffer"),
        field("b_external_id", String.class), // Change here
        field("b_buffer_type_id"),
        field("b_entrypoints", Object.class), // Change here
        field("b_site_id"),
        field("b_state", String.class), // Change here
        field("b_uri", String.class)) // Change here
    .select(select(
            inline(null, String.class),
            field("bt_id"),
            inline(null, Object.class),
            field("s_id"),
            inline(null, String.class),
            inline(null, String.class))
            .from(table("repository.site"), table("repository.buffer_type"))
            .where(field("s_name").eq(cast(null, String.class)))
            .and(field("bt_external_id").eq(cast(null, Integer.class))))
        .onConflict().doNothing()
    .getSQL();

Or even better, use the code generator, in case of which all of this will be done for you automatically, improving readability.

Upvotes: 2

Related Questions