枚举和不同数据库的 Jooq 问题
Jooq Problem with Enums and different databases
我正在使用 jooq,我正在尝试使用 punishment
枚举,但是当我尝试执行插入语句时,我得到以下信息:
org.jooq.exception.DataAccessException: SQL [insert into "punishments" ("userId", "guildId", "punishment", "startData", "expired", "reason", "operator", "id", "endData") values (?, ?, ?, ?, ?, ?, ?, ?, ?)]; ERROR: column "punishment" is of type punishment but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 142
我如何生成代码
使用 Gradle、flyway 和 jooq 插件,我能够迁移 h2 数据库,然后在其上使用 jooq 生成代码。
以下是我的jooq配置(在build.gradle里面)
jooq {
version = '3.16.5'
edition = nu.studer.gradle.jooq.JooqEdition.OSS
configurations {
main {
generateSchemaSourceOnCompilation = true
generationTool {
jdbc {
driver = 'org.h2.Driver'
url = "jdbc:h2:file:${project.buildDir}/migration/h2;MODE=PostgreSQL"
user = 'SA'
password = ''
properties {
property {
key = 'ssl'
value = 'false'
}
}
}
generator {
name = 'org.jooq.codegen.JavaGenerator'
database {
name = 'org.jooq.meta.h2.H2Database'
inputSchema = 'PUBLIC'
outputSchema = ''
}
generate {
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
}
target {
packageName = 'me.bluetree242.bbot.jooq'
}
strategy.name = 'org.jooq.codegen.DefaultGeneratorStrategy'
strategy {
matchers {
tables {
table {
tableClass {
transform = "PASCAL"
expression = "$0_TABLE"
}
}
}
enums {
"enum" {
enumClass {
transform = "PASCAL"
expression = "$0_ENUM"
}
}
}
}
}
}
}
}
}
}
下面是sql用来创建table和enum
CREATE TYPE punishment AS ENUM ('MUTE', 'BAN', 'QUARANTINE', 'TIMEOUT', 'KICK');
CREATE TABLE punishments(
"userId" BIGINT NOT NULL,
"guildId" BIGINT NOT NULL,
"punishment" punishment NOT NULL ,
"expired" boolean NOT NULL,
"operator" BIGINT,
"reason" text,
"endDate" BIGINT,
"id" integer,
"startDate" BIGINT NOT NULL
)
这是我要插入的代码
jooq.insertInto(PunishmentsTable.PUNISHMENTS)
.set(PunishmentsTable.PUNISHMENTS.USERID, userId)
.set(PunishmentsTable.PUNISHMENTS.GUILDID, guild.getId())
.set(PunishmentsTable.PUNISHMENTS.PUNISHMENT, type.asJooq())
.set(PunishmentsTable.PUNISHMENTS.STARTDATA, System.currentTimeMillis())
.set(PunishmentsTable.PUNISHMENTS.EXPIRED, !type.isSupportUndo())
.set(PunishmentsTable.PUNISHMENTS.REASON, operator.getReasonText(this))
.set(PunishmentsTable.PUNISHMENTS.OPERATOR, operator.getAsId())
.set(PunishmentsTable.PUNISHMENTS.ID, id)
.set(PunishmentsTable.PUNISHMENTS.ENDDATA, duration.toMillis() == 0 ? 0 : System.currentTimeMillis() + duration.toMillis())
.execute();
用于运行程序的数据库
使用 h2 生成,在 运行 运行程序时使用 postgreSQL
使用postgres生成代码时
如果我使用 postgres 生成代码,一切正常,但这对我来说不是一个选项构建必须不需要数据库,必须使用本地(如 h2)
为了解决这个问题,我不得不停止使用枚举,而使用类似的东西。我使用检查而不是枚举和 varchar,最后强制类型使用 java 的枚举。
这是我创建 table 的新查询,当然是在清除旧查询之后。
CREATE TABLE punishments(
"userId" BIGINT NOT NULL,
"guildId" BIGINT NOT NULL,
"punishmentType" varchar NOT NULL check ("punishmentType" in ('MUTE', 'BAN', 'QUARANTINE', 'TIMEOUT', 'KICK')),
"expired" boolean NOT NULL,
"operator" BIGINT,
"reason" text,
"endDate" BIGINT,
"id" integer,
"startDate" BIGINT NOT NULL
)
我正在使用 jooq,我正在尝试使用 punishment
枚举,但是当我尝试执行插入语句时,我得到以下信息:
org.jooq.exception.DataAccessException: SQL [insert into "punishments" ("userId", "guildId", "punishment", "startData", "expired", "reason", "operator", "id", "endData") values (?, ?, ?, ?, ?, ?, ?, ?, ?)]; ERROR: column "punishment" is of type punishment but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 142
我如何生成代码
使用 Gradle、flyway 和 jooq 插件,我能够迁移 h2 数据库,然后在其上使用 jooq 生成代码。
以下是我的jooq配置(在build.gradle里面)
jooq {
version = '3.16.5'
edition = nu.studer.gradle.jooq.JooqEdition.OSS
configurations {
main {
generateSchemaSourceOnCompilation = true
generationTool {
jdbc {
driver = 'org.h2.Driver'
url = "jdbc:h2:file:${project.buildDir}/migration/h2;MODE=PostgreSQL"
user = 'SA'
password = ''
properties {
property {
key = 'ssl'
value = 'false'
}
}
}
generator {
name = 'org.jooq.codegen.JavaGenerator'
database {
name = 'org.jooq.meta.h2.H2Database'
inputSchema = 'PUBLIC'
outputSchema = ''
}
generate {
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
}
target {
packageName = 'me.bluetree242.bbot.jooq'
}
strategy.name = 'org.jooq.codegen.DefaultGeneratorStrategy'
strategy {
matchers {
tables {
table {
tableClass {
transform = "PASCAL"
expression = "$0_TABLE"
}
}
}
enums {
"enum" {
enumClass {
transform = "PASCAL"
expression = "$0_ENUM"
}
}
}
}
}
}
}
}
}
}
下面是sql用来创建table和enum
CREATE TYPE punishment AS ENUM ('MUTE', 'BAN', 'QUARANTINE', 'TIMEOUT', 'KICK');
CREATE TABLE punishments(
"userId" BIGINT NOT NULL,
"guildId" BIGINT NOT NULL,
"punishment" punishment NOT NULL ,
"expired" boolean NOT NULL,
"operator" BIGINT,
"reason" text,
"endDate" BIGINT,
"id" integer,
"startDate" BIGINT NOT NULL
)
这是我要插入的代码
jooq.insertInto(PunishmentsTable.PUNISHMENTS)
.set(PunishmentsTable.PUNISHMENTS.USERID, userId)
.set(PunishmentsTable.PUNISHMENTS.GUILDID, guild.getId())
.set(PunishmentsTable.PUNISHMENTS.PUNISHMENT, type.asJooq())
.set(PunishmentsTable.PUNISHMENTS.STARTDATA, System.currentTimeMillis())
.set(PunishmentsTable.PUNISHMENTS.EXPIRED, !type.isSupportUndo())
.set(PunishmentsTable.PUNISHMENTS.REASON, operator.getReasonText(this))
.set(PunishmentsTable.PUNISHMENTS.OPERATOR, operator.getAsId())
.set(PunishmentsTable.PUNISHMENTS.ID, id)
.set(PunishmentsTable.PUNISHMENTS.ENDDATA, duration.toMillis() == 0 ? 0 : System.currentTimeMillis() + duration.toMillis())
.execute();
用于运行程序的数据库
使用 h2 生成,在 运行 运行程序时使用 postgreSQL
使用postgres生成代码时
如果我使用 postgres 生成代码,一切正常,但这对我来说不是一个选项构建必须不需要数据库,必须使用本地(如 h2)
为了解决这个问题,我不得不停止使用枚举,而使用类似的东西。我使用检查而不是枚举和 varchar,最后强制类型使用 java 的枚举。
这是我创建 table 的新查询,当然是在清除旧查询之后。
CREATE TABLE punishments(
"userId" BIGINT NOT NULL,
"guildId" BIGINT NOT NULL,
"punishmentType" varchar NOT NULL check ("punishmentType" in ('MUTE', 'BAN', 'QUARANTINE', 'TIMEOUT', 'KICK')),
"expired" boolean NOT NULL,
"operator" BIGINT,
"reason" text,
"endDate" BIGINT,
"id" integer,
"startDate" BIGINT NOT NULL
)