【问题标题】:Jooq doesn't use default value with store functionJooq 不使用存储功能的默认值
【发布时间】:2018-11-06 18:43:00
【问题描述】:

我尝试存储具有以下约束的尝试对象:

ALTER TABLE ATTEMPT ADD COLUMN files json NOT NULL DEFAULT '{}'::json;

和代码:

AttemptRecord attemptRecord = context.newRecord(T_ATTEMPT, attempt);
setAttemptId(attempt.getId());
store();

但是当我用 Jooq 存储它时,出现以下错误:

nested exception is org.postgresql.util.PSQLException: ERROR: null value in column "files" violates the not-null constraint

在此之前,我有一个 bytearray 列,而不是 json files 列,我在默认值下一切正常。 我也使用调试器工具,AttemptRecord 包含文件的这个值,这对我来说听起来很奇怪,但我不知道这是什么意思。

{NullNode@3189} "null"

如果 JsonNode 为空,它并不真正为空。

为什么 Jooq 忽略默认值?

【问题讨论】:

    标签: java postgresql jooq


    【解决方案1】:

    说明:

    问题在于你的电话

    AttemptRecord attemptRecord = context.newRecord(T_ATTEMPT, attempt);
    

    Consider the Javadoc:

    结果记录的所有值都将其内部“已更改”标志设置为 true。

    你的attempt POJO 没有办法区分

    • 具有 SQL DEFAULT 语义的 null
    • 具有 SQL NULL 语义的 null

    正因为如此,您通过传递 POJO(依次调用每列的记录设置器)来主动设置 files 列的值,最合理的默认行为是设置 @ 987654333@ 标志为该列的true,因此假设您要将null 值发送到数据库。

    如果不是这样,就会有相当多的 SQL 功能无法有效使用,包括例如一些仅在插入/更新的某些列上触发的触发器。

    我最近也在一篇博文中记录了这一点:https://blog.jooq.org/2018/11/05/how-to-use-jooqs-updatablerecord-for-crud-to-apply-a-delta/

    解决方法:针对单个案例修复此问题:

    在这种情况下,解决方法可能是使用以下命令重置 changed() 列的 changed() 标志:

    attemptRecord.changed(ATTEMPT.FILES, false);
    

    解决方法:为所有 store() 方法调用修复此问题

    更彻底的修复可能是实现RecordListener,它在每次运行store()insert()update() 调用之前触发,允许您修补存储的记录。

    更多信息在这里:https://www.jooq.org/doc/latest/manual/sql-execution/crud-with-updatablerecords/crud-record-listener

    【讨论】:

    • 谢谢,我现在明白了,所以我想在我的情况下使用jooq.org/javadoc/latest/org/jooq/… 更好?
    • @Limmy:这不会改变任何东西,它仍然会简单地插入所有“改变”的值
    猜你喜欢
    • 2012-03-28
    • 1970-01-01
    • 2010-11-11
    • 2023-02-13
    • 1970-01-01
    • 2019-05-02
    • 2023-02-07
    • 2010-09-14
    • 1970-01-01
    相关资源
    最近更新 更多