postgresql 为什么Jooq无法识别类型?

mrwjdhj3  于 2023-03-08  发布在  PostgreSQL
关注(0)|答案(1)|浏览(132)

我有一个枚举SomeType,结构如下:

enum class SomeType {
    Type1, 
    Type2
}

我也有一个包含该枚举的表:

create type users.some_type as enum ('Type1','Type2');
create table users.some
(
    id   bigint default nextval('users.some_seq'),
    type users.some_type not null,
    primary key (id)
);

枚举生成为:

@Suppress("UNCHECKED_CAST")
enum class SomeType(@get:JvmName("literal") public val literal: String) : EnumType {
    Type1("Type1"),
    Type2("Type2");
    override fun getCatalog(): Catalog? = schema.catalog
    override fun getSchema(): Schema = Users.USERS
    override fun getName(): String = "some_type"
    override fun getLiteral(): String = literal
}

然而,当我尝试为该表编写insert方法时,它无法识别枚举类型:

@Transactional
    fun save(some: Some) =
        dslContext.insertInto(
            SOME,SOME.TYPE,
        ).values(some.someType)

我使用的是Kotlin和Postgres,但我不认为此问题是Kotlin特有的

8fq7wneg

8fq7wneg1#

为什么不起作用

jOOQ只能自动将EnumType枚举Map到PostgreSQL enum类型,而不能自定义枚举类型。主要原因包括:

  • 类型名称在许多类型的查询中是相关的,其中绑定变量必须被强制转换为正确的类型,例如cast(? as users.some_type)或当使用数组时:cast(? as users.some_type[])。否则,它就不能与pgjdbc一起工作。
  • 一些PostgreSQL枚举值在Java/Kotlin/JVM中可能是非法的标识符,因此需要为每个值定义EnumType.getLiteral(),即使在许多情况下,它与枚举的Java/kotlin文本值相同。

因此,你不能期望你自己的用户定义类型“只是工作”。事实上,它是一个enum并没有改变这一点。这与例如PostgreSQL中的BIGINT列被Map到MyType没有什么不同。jOOQ不能只是假设任何Map。

如何让它工作

您可以轻松地将一个enumConverter(或any other type of converter)附加到生成的列中,在后台,jOOQ仍然会使用生成的转换器进行变量绑定,但至少在用户代码中,您现在只能看到自己的类型。

相关问题