[英]JOOQ fetch record from table and insert it into another table
我想从一个表中选择所有字段,提取到另一个表的记录中,然后将记录插入到该表中。 但是,我收到一条错误消息,指出这些值为空。 这是相关的一段代码:
// Fetch
PersonDeactivatedRecord person = getContext().selectFrom(PERSON)
.where(PERSON.ID.eq(id))
.fetchOneInto(PersonDeactivatedRecord.class);
// Insert
person.setDeactivatedOn(new Timestamp(System.currentTimeMillis()));
getContext().insertInto(PERSON_DEACTIVATED)
.set(person)
.execute();
person_deactivated
表是person
表的副本加上一列 (deactivated_on)。 我得到的错误是这样的:
org.jooq.exception.DataAccessException: SQL [insert into "xxx"."person_deactivated" ("deactivated_on") values (cast(? as timestamp))]; ERROR: null value in column "id" violates not-null constraint
Detail: Failing row contains (null, null, null, null, null, null, null, null, null, ...)
请注意,当我调试此代码时,我看到person
对象已按预期完全填充。 知道我在这里缺少什么吗?
InsertSetStep.set(Record)
方法不会将整个person
记录插入到目标表中,而是只考虑那些值“已更改”的字段。 请参阅 Javadoc:
这与调用
set(Map)
并将参数记录视为Map<Field<?>, Object>
,除了考虑Record.changed()
标志以便仅更新更改的值。
因此,您有多种可能来解决此问题(当然,我在这里列出的不止这些):
这将是最简单的修复:
// Insert
person.setDeactivatedOn(new Timestamp(System.currentTimeMillis()));
person.changed(true); // Sets all flags to true
getContext().insertInto(PERSON_DEACTIVATED)
.set(person)
.execute();
此解决方案的优点是您只有一个查询,这意味着:
所以,你可以写:
getContext()
.insertInto(PERSON_DEACTIVATED)
.columns(PERSON_DEACTIVATED.fields())
.select(
select(Arrays
.stream(PERSON_DEACTIVATED.fields())
.map(f -> f.equals(PERSON_DEACTIVATED.DEACTIVATED_ON)
? currentTimestamp()
: PERSON.field(f))
.collect(Collectors.toList()))
.from(PERSON)
.where(PERSON.ID.eq(id))
)
.execute();
与往常一样,此答案假设您的代码中有以下静态导入:
import static org.jooq.impl.DSL.*;
上述查询将PERSON
所有列插入到PERSON_DEACTIVATED
,除了DEACTIVATED_ON
列将被当前时间戳替换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.