使用jOOQ将枚举值插入未知表

时间:2018-10-15 09:53:58

标签: 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 (?)];错误:列“ direction”的类型为direction,但表达式的类型为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:方言java.lang.Enum中不支持类型类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 (?)];错误:列“ direction”的类型为direction,但表达式的类型为character varying


是否可以使用jOOQ将带有枚举列的“未知”(未生成)表插入到表中?

1 个答案:

答案 0 :(得分:1)

对您现有尝试的评论:

  

完全不用打字

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

  

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

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

关于“(会吗?我绝对将我的方言设置为SQLDialect.POSTGRES_9_5。)”

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

解决方案

您很亲密:

  

使用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";
    }
}