Search code examples
kotlinjooq

JOOQ: Enum inserted at varchar even after forcing the type


I have an enum in Postgres 12 as

CREATE TYPE some_type AS ENUM ('YES', 'NO', 'MAYBE');

I created a user enum class (Kotlin)

enum class SomeType {
    YES, NO, MAYBE;
}

and forced the type as at Gradle (kotlin script)

                        forcedTypes = listOf(
                            ForcedType().apply {
                                setUserType("com.example.SomeType")
                                setEnumConverter(true)
                                setIncludeExpression("column_a")
                            },
                        )


I want to batch insert data for table with a column of type - some_type. Following is the way I do it.


 val query = insertInto(TABLE_NAME)
                        .columns(
                            COLUMN_A, // some_type
                        )
                        .values(MAYBE, LocalDateTime.now())
                        .onDuplicateKeyUpdate()
                        .set(COLUMN_A, YES)

                },

query.bind(YES).executeAsync()

The code generated is typesafe with COLUMN_A of type Field<SomeType> and not Field<ANY>, however insert fails at runtime with following error


ERROR: column "column_a" is of type some_type but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

I see with the debugger at the org.jooq.impl.BatchSingle on function

public final BatchSingle bind(Object... bindValues) {
        allBindValues.add(bindValues);
        return this;
    }

That the prepared query is sending varchar

insert into "public"."sometable" (
  "column_a",
  "record_timestamp"
)
values (
  'MAYBE'
)

Am I missing some config somewhere?


Solution

  • You have 2 bind values in your query:

    • LocalDateTime.now()
    • YES

    However, when batching, you're binding only 1. Just pass both of them to the batch:

    query.bind(LocalDateTime.now(), YES).executeAsync()