尝试使用 POJO 记录更新表时出现 Java jOOQ 问题
Posted
技术标签:
【中文标题】尝试使用 POJO 记录更新表时出现 Java jOOQ 问题【英文标题】:Java jOOQ issue when trying to update a table using a POJO Record 【发布时间】:2018-11-22 01:03:21 【问题描述】:我正在尝试执行一个简单的 updateRecord 函数,但它给了我一个错误,我找不到原因或任何其他人有它。
可以在以下位置找到示例测试项目: https://github.com/billbarni/jooq-studer-h2-test
Java 代码:
import static mypackage.database.model.h2.public_.Tables.EXPRESSAO;
import mypackage.database.model.h2.public_.tables.pojos.Expressao;
import mypackage.database.model.h2.public_.tables.records.ExpressaoRecord;
public void updateQuery(Expressao expressaoPojo)
ExpressaoRecord expressaoRecord = ctx.newRecord(EXPRESSAO, expressaoPojo);
ctx.executeUpdate(expressaoRecord); // Error with this parameter
数据库创建表达式:
CREATE TABLE
expressao (
id INT AUTO_INCREMENT PRIMARY KEY NOT NULL,
nome VARCHAR(50) NOT NULL,
conteudo VARCHAR NOT NULL,
qtd_tempo INT NOT NULL,
tipo_tempo VARCHAR(5) NOT NULL,
data_inicial TIMESTAMP NOT NULL
);
Gradle 生成器配置:
plugins
id 'nu.studer.jooq' version '2.0.9'
dependencies
compile group: 'org.jooq', name: 'jooq-codegen', version: '3.10.4'
jooqRuntime 'com.h2database:h2:1.4.197'
jooq
h2(sourceSets.main)
jdbc
driver = 'org.h2.Driver'
url = 'jdbc:h2:file:./db'
user = 'sa'
password = ''
generator
name = 'org.jooq.util.DefaultGenerator'
strategy
name = 'org.jooq.util.DefaultGeneratorStrategy'
database
name = 'org.jooq.util.h2.H2Database'
generate
relations = true
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
target
packageName = 'mypackage.database.model.h2'
directory = 'src/main/java'
Java 在编译之前给了我这个错误:
DSLContext 中的executeUpdate (R) 无法应用于 (mypackage.database.model.h2.public_.tables.records.ExpressaoRecord) 原因:不存在类型变量 R 的实例,因此 ExpressaoRecord 符合 UpdatableRecord
这个问题背后的原因是什么?我做错了什么?
Obs.:我有 2 个数据库(firebird 和 h2),我使用 Gradle 的 jOOQ 生成器自动生成 pojos 和其他类。他们不共享 POJO 或任何复杂的东西。这个项目非常小而且简单。
Obs 2.:我使用了多个版本的 jOOQ 库(从 3.9 到新的 3.11),问题仍然存在。
Lukas Eder,jOOQ 之神,我等待你的归来,将我从这冗长的沉睡中解救出来。
【问题讨论】:
我来为您解除痛苦。您可以发布EXPRESSAO
表的 DDL (CREATE TABLE
) 吗?
备案,这个问题也已经反馈给gradle-jooq-plugin:github.com/etiennestuder/gradle-jooq-plugin/issues/73
【参考方案1】:
DSLContext.executeUpdate(R)
要求 R
是 UpdatableRecord
的子类型,这是有道理的。只有“可更新”(即知道其主键)的记录才能有效更新。
您的ExpressaoRecord
似乎不是UpdatableRecord
,而只是TableRecord
。这可能有几个原因:
您在代码生成器中停用了<relations/>
标志
<relations>false</relations>
可以用来关闭所有关系相关特征的生成,包括主键、外键信息。如果没有这些信息,您实际上无法生成UpdatableRecord
类型。
您的表没有主键。
没有主键,代码生成器不会生成UpdatableRecord
。
您可以向表中添加一个主键,或者告诉代码生成器一个“合成主键”:
https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-synthetic-primary-keys/
或者,您可以通过将任何唯一键视为主键来“覆盖”您的主键:
https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-override-primary-keys/
【讨论】:
抱歉,我花了这么长时间才更新我的问题。我的表的 CREATE 现在包括在内。也许我应该使用其他sintax呢? H2 接受了那个,但在列标志中做错了什么? @MBarni:好的,所以假设 #1 尚未得到证实。你能发布你的代码生成配置吗? 使用 gradle 配置更新的问题。我正在使用第三方插件,可能是导致问题的原因? @MBarni:在第三方插件中,这将是一个非常重要的问题,您不会是唯一遭受它的人,所以我将其排除为可能的原因。此外,您的配置看起来正确。再检查一件事:您的ExpressaoRecord
是否扩展UpdatableRecordImpl
?如果您删除 includes
规范,问题是否仍然存在?
@MBarni:这真的很奇怪。明天我会尝试重现这个。毕竟这可能是第三方插件的问题......【参考方案2】:
问题似乎出在nu.studer.jooq 插件上,因为当使用另一个代码生成器时,反映具有主键的表的 H2 数据库模型类会收到 UpdatableTable 扩展/实现。
我在插件上开了一个issue,想要关注的可以在上面已经链接几行的插件github页面查看open issues。
插件的新版本(版本 3.x+)似乎已经解决了这个问题。升级时要小心,因为插件配置中有许多重大更改,它也会强制使用新的 jOOQ 版本(3.11+)。
【讨论】:
以上是关于尝试使用 POJO 记录更新表时出现 Java jOOQ 问题的主要内容,如果未能解决你的问题,请参考以下文章
CloudKit-更新记录:使用“saveRecord”更新记录时出现“客户端 oplock 错误”
使用 oledbcommand.executeNonQuery() 更新 MS Access 记录时出现问题,结果未更新