java - 使用 jOOQ 将枚举值插入到未知表中

标签 java postgresql enums jooq

给定一个带有枚举列的表,如下所示:

CREATE TYPE DIRECTION AS ENUM ('NORTH', 'EAST', 'SOUTH', 'WEST');

CREATE TABLE enum_table (
    direction DIRECTION NOT NULL
);

如何使用 jOOQ 在不为整个表生成 Java 代码的情况下插入上述表?对于这个特定实例,由于其他技术限制,我不能(还)简单地生成代码。如果有帮助,我可以复制粘贴一段生成的代码(例如类型定义),但整个表格太多了。

我尝试过的:

  • 根本不需要打字:

    context.insertInto(table("enum_table"))
        .columns(field("direction"))
        .values("west")
        .execute();
    

    正如预期的那样,这会引发不兼容的类型:

    org.jooq.exception.DataAccessException: SQL [insert into enum_table (direction) values (?)]; ERROR: column "direction" is of type direction but expression is of type character varying.

  • 列类型为 Enum.class + 强制或转换为 Enum.class:

    context.insertInto(table("enum_table"))
        .columns(field("direction", Enum.class))
        .values(DSL.coerce("west", Enum.class))  // or DSL.cast(), same result
        .execute();
    

    抛出这个:

    org.jooq.exception.SQLDialectNotSupportedException: Type class java.lang.Enum is not supported in dialect DEFAULT.

    (哇?我绝对已将我的方言设置为 SQLDialect.POSTGRES_9_5。)

  • 在 Java 中创建一个临时枚举:

    private enum Direction implements EnumType {
        NORTH, EAST, SOUTH, WEST;
    
        @Override
        public String getLiteral() {
            return this.name();
        }
    
        @Override
        public String getName() {
            return "direction";
        }
    }
    
    // and then
    context.insertInto(table("enum_table"))
        .columns(field("direction", Direction.class))
        .values(Direction.WEST)
        .execute();
    

    还尝试了另一种选择 - 同样的结果:

    .columns(field("direction", SQLDataType.VARCHAR.nullable(false).asEnumDataType(Direction.class)))
    

    再次抛出不兼容类型异常:

    org.jooq.exception.DataAccessException: SQL [insert into enum_table (direction) values (?)]; ERROR: column "direction" is of type direction but expression is of type character varying.


有没有什么方法可以使用 jOOQ 将枚举列插入到“未知”(未生成)表中?

最佳答案

对您现有尝试的评论:

No typing at all

那是行不通的。 jOOQ(或者更确切地说是 PostgreSQL)需要类型信息来绑定(bind)枚举变量。当然,这是一种耻辱,因为从字符串到枚举的转换可以看作是直接的,因此可以隐式完成。但 PostgreSQL 目前不以这种方式工作。

Column type as Enum.class + coercing or casting to Enum.class

由于同样的原因,这仍然不起作用。现在,jOOQ 知道我们正在处理一个枚举(它之前知道值是否为非空),但我们不知道我们需要将绑定(bind)变量转换为的 PostgreSQL 枚举类型。

关于 “(哇?我绝对已经将我的方言设置为 SQLDialect.POSTGRES_9_5。)”:

如果您查看堆栈跟踪的来源,那就是当您将 Enum.class 传递给 DSL.field() 时。在该静态方法中,上下文中没有方言,所以这就是出现此错误消息的原因。

解决方案

你很接近:

Creating an ad-hoc enum in Java

在 PostgreSQL 中使用 EnumType 时,还需要返回 Schema 引用。这是为了区分使用 PostgreSQL 或 MariaDB/MySQL 生成的 EnumType 实例。这可能不是绝对必要的。将通过 https://github.com/jOOQ/jOOQ/issues/7941 检查

现在,试试这个:

private enum Direction implements EnumType {
    NORTH, EAST, SOUTH, WEST;

    @Override
    public String getLiteral() {
        return this.name();
    }

    @Override
    public Schema getSchema() {
        return MY_SCHEMA;
    }

    @Override
    public String getName() {
        return "direction";
    }
}

关于java - 使用 jOOQ 将枚举值插入到未知表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52814083/

相关文章:

java - 如何检测线程何时在 Java 中遇到断点

java - 在类构造函数中初始化一个数组

postgresql - 如何将字符串拆分为 x 列和 y 行?

Postgresql 从表中获取最后几行

postgresql - 使用从表本身中选择的表插入数据

java - 如何使用 PowerMock 和 Mockito 模拟枚举类的实例?

csv - 在 Rust 中使用带有 serde 的嵌套枚举/结构序列化/反序列化 CSV

java - 我怎样才能在我的 Android 应用程序中拥有图标列表;

java - 编写计算复利的方法

c# - 是否可以根据枚举输入返回泛型类?