Jooq не использует значение по умолчанию с функцией магазина - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь сохранить объект попытки со следующим ограничением:

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 Ответ

0 голосов
/ 30 октября 2018

Пояснение:

Проблема с вашим звонком

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

Рассмотрим Javadoc :

В результирующей записи для всех значений будут установлены внутренние "измененные" флаги.

Ваш attempt POJO не может отличить

  • a null значение с семантикой SQL DEFAULT
  • a null значение с семантикой SQL NULL

Из-за того факта, что вы активно устанавливаете значение столбца files, передавая POJO (который, в свою очередь, вызывает установщик записей для каждого столбца), наиболее разумным поведением по умолчанию является установка changed() флаг для true для этого столбца и, таким образом, предполагается, что вы хотите отправить значение null в базу данных.

Если бы это было не так, было бы довольно много функций SQL, которые нельзя было бы эффективно использовать, включая, например, некоторые триггеры, которые срабатывают только при вставке / обновлении определенных столбцов.

Я также недавно задокументировал это в своем блоге: https://blog.jooq.org/2018/11/05/how-to-use-jooqs-updatablerecord-for-crud-to-apply-a-delta/

Обходной путь: Исправьте это для отдельного случая:

Обходной путь в этом случае может состоять в том, чтобы сбросить флаг changed() для столбца files, используя:

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

...