有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaJooq不使用存储函数的默认值

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

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

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

{NullNode@3189} "null"

它并不像JsonNode是空的那样是空的

为什么Jooq忽略默认值


共 (1) 个答案

  1. # 1 楼答案

    说明:

    问题在于你的电话

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

    Consider the Javadoc

    The resulting record will have its internal "changed" flags set to true for all values.

    您的attemptPOJO无法区分

    • 语义为SQL DEFAULTnull
    • 语义为SQL的nullNULL

    因此,您通过传递POJO(它反过来调用每个列的记录设置程序)来主动设置files列的值,最合理的默认行为是为该列将changed()标志设置为true,因此假设您希望向数据库发送null

    如果不是这样的话,可能会有很多SQL功能无法有效使用,包括一些仅在插入/更新的特定列上触发的触发器

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

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

    这种情况下的解决方法是使用以下方法重置files列的changed()标志:

    attemptRecord.changed(ATTEMPT.FILES, false);
    

    解决方法:修复所有store()方法调用

    更彻底的修复方法可能是实现^{},它在每次运行store()、或insert()、或update()调用之前都会触发,从而允许您修补存储的记录

    更多信息请参见:https://www.jooq.org/doc/latest/manual/sql-execution/crud-with-updatablerecords/crud-record-listener