java - 使用 jOOQ 将枚举值插入到未知表中
问题描述
给定一个带有枚举列的表,如下所示:
CREATE TYPE DIRECTION AS ENUM ('NORTH', 'EAST', 'SOUTH', 'WEST');
CREATE TABLE enum_table (
direction DIRECTION NOT NULL
);
如何在不为整个表生成 Java 代码的情况下使用 jOOQ 插入所述表?对于这个特定的例子,由于其他技术限制,我(还)不能简单地生成代码。如果有帮助,我可以复制粘贴一段生成的代码(例如类型定义),但整个表格太多了。
我尝试了什么:
根本不用打字:
context.insertInto(table("enum_table")) .columns(field("direction")) .values("west") .execute();
正如预期的那样,这会引发不兼容的类型:
org.jooq.exception.DataAccessException
: SQL [insert into enum_table (direction) values (?)
]; 错误:列“方向”是类型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
。(Wut?我绝对将我的方言设置为
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
,但表达式是类型character varying
。
有没有办法使用 jOOQ 插入带有枚举列的“未知”(未生成)表?
解决方案
对您现有尝试的评论:
根本不用打字
那是行不通的。jOOQ(或者更确切地说是 PostgreSQL)需要类型信息来绑定枚举变量。当然,这是一种耻辱,因为从字符串到枚举的转换可以看作是直接的,所以它可以隐式完成。但是 PostgreSQL 目前不能以这种方式工作。
列类型为 Enum.class + 强制或强制转换为 Enum.class
由于同样的原因,这仍然不起作用。现在,jOOQ 知道我们正在处理一个枚举(它之前知道该值是否为非 null),但我们不知道 PostgreSQL 枚举类型,我们需要将绑定变量转换为该类型。
关于“(Wut?我绝对将我的方言设置为SQLDialect.POSTGRES_9_5。)”:
如果您查看堆栈跟踪的来源,那就是您传递Enum.class
到DSL.field()
. 在该静态方法中,上下文中没有方言,这就是出现此错误消息的原因。
解决方案
你很接近:
在 Java 中创建临时枚举
在 PostgreSQL 中使用EnumType
时,还需要返回Schema
引用。这是为了区分EnumType
使用 PostgreSQL 或 MariaDB/MySQL 生成的实例。这可能不是绝对必要的。将通过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 - 如何获取相同视图组件的列表
- python - 错误计算区域“IndexError:维度 1 的张量的索引过多”
- dockerfile - docker hyperledger indy 上的 node-gyp 重建错误
- containers - Podman oci .containerenv:不是目录
- python - 设置 DeepDiff 以很好地识别删除
- sql - 如何通过算法从帐户树中选择适当的帐户
- github - 仅在 GitHub Actions 中发布更改的项目
- r - 在 R 包中使用 %>%
- c# - 如何从 .Net Core 控制台应用程序分配 Azure DevOps 中的变量
- docker - 将 png 图像添加到 Dockerfile