【发布时间】:2018-04-16 22:24:58
【问题描述】:
我想我错过了关于 UpdatableRecord.update() 工作原理的重要内容。
不起作用的示例代码:
MailKeywordRealAddressRecord linkRecord = dsl.select().
from(MAIL_KEYWORD_REAL_ADDRESS).
where(MAIL_KEYWORD_REAL_ADDRESS.MAIL_KEYWORD_ID.eq(mailKeyword.getId())).
fetchOneInto(MailKeywordRealAddressRecord.class);
if( linkRecord == null ){
log.debug("no link record found for our mailKeyword");
linkRecord = dsl.newRecord(MAIL_KEYWORD_REAL_ADDRESS);
linkRecord.setMailKeywordId(mailKeyword.getId());
linkRecord.setRealAddressId(realAddress.getId());
linkRecord.insert();
}
else {
// 1 - will geta "DataChangedException" because it tries to do a
// "select ... for udpate" with the *new* realAddress id
log.debug("updating old linkRecord from: {}", linkRecord );
linkRecord.setRealAddressId(realAddress.getId());
linkRecord.update();
// 2 - working
// log.debug("updating old linkRecord from: {}", linkRecord );
// linkRecord.delete();
// linkRecord.setRealAddressId(realAddress.getId());
// linkRecord.insert();
}
这将导致异常:
DataChangedException: 数据库记录不再存在
如果我查看 SQL,JOOQ 正在使用 RealAddressId 的 new 值发出 select for update SQL 语句。
如果我注释掉 (1) 块并使用 (2) - JOOQ 似乎做了我想做的事,它会删除旧记录并更新新记录。
MailKeywordRealAddressRecord 下面的表是一个普通的多对多链接表(两列,都被声明为复合主键)。
考虑一下... - 是这个问题吗?我正在更新主键列? 我很高兴坚持删除/插入逻辑(或者我可以重构为直接的 SQL 语句)——只是想弄清楚发生了什么。
数据库是 Postgres,JOOQ 版本是 3.10.1。
【问题讨论】:
-
您在使用
Settings.executeWithOptimisticLockingIncludeUnversioned功能吗?当您启用该功能时,您的期望是什么? -
@LukasEder JOOQ 代码生成设置可以在这里找到:bitbucket.org/snippets/shorn/64RnL5/jooq-subproject 在我的 Spring 设置中,JOOQ 设置配置为“withExecuteWithOptimisticLocking(true)”。
-
就我对该功能的期望而言 - 我不会认为它与没有版本字段的记录相关。
-
嗯,该功能确实是说:“使用乐观锁定执行,包括那些没有版本字段的记录”。我会提供答案。