简体   繁体   English

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

[英]Insert an enum value into an unknown table with jOOQ

Given a table with an enum column, like this: 给定一个包含枚举列的表,如下所示:

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

CREATE TABLE enum_table (
    direction DIRECTION NOT NULL
);

How do I insert into the said table using jOOQ without generating Java code for the whole table ? 如何使用jOOQ插入到表中而不为整个表生成Java代码 For this particular instance, I cannot (yet) simply generate the code due to other technical restrictions. 对于这个特定的实例,由于其他技术限制,我不能(还)简单地生成代码。 I could copy-paste a piece of generated code (a type definition eg) if that helps, but the whole table is too much. 我可以复制粘贴一段生成的代码(例如类型定义),如果这有帮助,但整个表太多了。

What I tried: 我尝试了什么:

  • No typing at all: 根本没有打字:

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

    As expected, this throws on incompatible types: 正如预期的那样,这会引发不兼容的类型:

    org.jooq.exception.DataAccessException : SQL [ insert into enum_table (direction) values (?) ]; 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 . 错误:列“方向”是类型direction但表达式的类型是character varying

  • Column type as Enum.class + coercing or casting to Enum.class : 列类型为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(); 

    which throws this: 抛出这个:

    org.jooq.exception.SQLDialectNotSupportedException : Type class java.lang.Enum is not supported in dialect DEFAULT . org.jooq.exception.SQLDialectNotSupportedException :方言DEFAULT不支持类型类java.lang.Enum

    (Wut? I absolutely have set my dialect to SQLDialect.POSTGRES_9_5 .) (哇?我绝对把我的方言设置为SQLDialect.POSTGRES_9_5 。)

  • Creating an ad-hoc enum in Java: 在Java中创建ad-hoc枚举:

     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(); 

    Also tried an alternative - same result: 也尝试了另一种选择 - 相同的结果:

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

    Throws the incompatible types exception again: 再次引发不兼容的类型异常:

    org.jooq.exception.DataAccessException : SQL [ insert into enum_table (direction) values (?) ]; 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 . 错误:列“方向”是类型direction但表达式的类型是character varying


Is there any way to insert into an "unknown" (not generated) table with an enum column using jOOQ? 有没有办法使用jOOQ插入带有枚举列的“未知”(未生成)表?

Comments on your existing attempts: 对您现有尝试的评论:

No typing at all 根本没有打字

That doesn't work. 这不起作用。 jOOQ (or rather PostgreSQL) needs type information to bind an enum variable. jOOQ(或者更确切地说是PostgreSQL)需要类型信息来绑定枚举变量。 This is a shame, of course, because the conversion from strings to enums could be seen as straight forward, so it could be done implicitly. 当然,这是一种耻辱,因为从字符串到枚举的转换可以看作是直接的,因此可以隐式地完成。 But PostgreSQL currently doesn't work this way. 但PostgreSQL目前无法正常工作。

Column type as Enum.class + coercing or casting to Enum.class 列类型为Enum.class +强制转换或转换为Enum.class

This still doesn't work, because of the same reason. 由于同样的原因,这仍然不起作用。 Now, jOOQ knows that we're dealing with an enum (it knew before, if the value was non-null), but we don't know the PostgreSQL enum type, which we need to cast the bind variable to. 现在,jOOQ知道我们正在处理枚举(它之前知道,如果值是非null),但是我们不知道PostgreSQL枚举类型,我们需要将绑定变量转换为。

Regarding "(Wut? I absolutely have set my dialect to SQLDialect.POSTGRES_9_5.)" : 关于“(但是?我绝对将我的方言设置为SQLDialect.POSTGRES_9_5。)”

If you look at where the stack trace originates, it's when you pass Enum.class to DSL.field() . 如果你看一下堆栈跟踪的起源,那就是当你将Enum.class传递给DSL.field() In that static method, there's no dialect in the context, so that's why this error message appears. 在该静态方法中,上下文中没有方言,因此出现此错误消息的原因。

Solution

You were close: 你很亲密:

Creating an ad-hoc enum in Java 在Java中创建ad-hoc枚举

When using EnumType in PostgreSQL, you need to also return the Schema reference. 在PostgreSQL中使用EnumType时,还需要返回Schema引用。 This is to distinguish between EnumType instances that have been generated with PostgreSQL or MariaDB/MySQL. 这是为了区分使用PostgreSQL或MariaDB / MySQL生成的EnumType实例。 This probably shouldn't be strictly necessary. 这可能不是绝对必要的。 Will check that through https://github.com/jOOQ/jOOQ/issues/7941 将通过https://github.com/jOOQ/jOOQ/issues/7941检查

For now, try this: 现在,试试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM