Избегайте добавлять значения "null" в таблицу базы данных через JPA
im, начиная с JPA2 и до сих пор чувствуя себя довольно комфортно. Но у меня проблема при сохранении сущностей с нулевыми значениями свойств для полей базы данных NON NULL со значением по умолчанию.
Я хотел бы оставить свойство entity null и позволить базе данных вставить значение по умолчанию.
Моя текущая настройка - openJPA с PostgreSQL.
У меня есть эта таблица базы данных VERSION (Vorgabewert = Значение по умолчанию):
Spalte | Typ | Attribute
----------------+-----------------------------+----------------------------
status_ | smallint | not null Vorgabewert 0
time_ | timestamp without time zone | not null
system_time | timestamp without time zone | not null Vorgabewert now()
version | character varying(20) | not null
activationtime | timestamp without time zone |
importtime | timestamp without time zone |
У меня есть сущность (Java DTO), которая отображает поля базы данных (кроме "status" ) с помощью конфигурации xml.
Я надеялся, что смогу вставить объект без набора system_time
и ожидать, что база данных заполнит текущее время как значение по умолчанию.
JPA создает следующий SQL-запрос:
INSERT INTO public.version (version, activationtime, importtime, system_time, time_) VALUES (?, ?, ?, ?, ?) [params=?, ?, ?, ?, ?]
и Postgres реагирует с:
FEHLER: NULL-Wert in Spalte »system_time« verletzt Not-Null-Constraint
(извините за немецкий язык, но это сообщение означает нарушение Not-Null-Constraint в 'system_time').
Так что я могу сделать? Является ли это проблемой JPA или базы данных.
Могу ли я настроить JPA для исключения свойств null из инструкции SQL INSERT.
Я хочу иметь возможность установить "system_time" в моем объекте или позволить ему быть "null" и дать базе данных значение по умолчанию.
Любая помощь приветствуется!
Regads Клаус
Ответы
Ответ 1
Я бы не стал полагаться на значения по умолчанию в базе данных в сочетании с JPA. Вам нужно будет прочитать объект назад после вставки, иначе у вас будет несоответствие между состоянием сущности и состоянием db.
Выберите прагматичный подход и инициализируйте все значения в java. Никогда не слышал о том, как сообщить JPA/Hibernate о том, чтобы исключить нулевые значения в вставке/обновлении.
Ответ 2
Использование аннотации
@Column(insertable = false)
предотвратит генерирование значения в sql.
Ответ 3
В аннотации @Column поместите атрибут insertable в false следующим образом:
`@Column(name="system_time", insertable = false)`
Или, если вам нужно проверить, когда значение равно NULL, сделайте триггер ПЕРЕД ВСТАВКОЙ в таблице.
Ответ 4
Из документации: columnDefinition: фрагмент SQL, который используется при создании DDL для столбца.
Используя columnDefinition, вы можете указать ограничения по мере необходимости.
@Column(name="COLUMN_NAME",
columnDefinition="DATE DEFAULT CURRENT_DATE",table="TABLE_NAME")
В противном случае вы можете попытаться инициализировать поле в самой сущности, чтобы избавиться от этого.
@Column(name = "somedate", nullable = false)
private Date someDate = new Date();
Поэтому по умолчанию текущая дата будет вставлена, если вы ее не установите.
Ответ 5
Я нашел простое решение: определить значение по умолчанию в pojo.
@Column(name="system_time")
private Date systemTime = new Date();
Ответ 6
Я использую это (для базы данных Oracle):
@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATION_TIME",
columnDefinition="TIMESTAMP DEFAULT SYSTIMESTAMP",
nullable=false,
insertable=false,
updatable=false)
private Date creationTime;
Ответ 7
вы можете избежать свойства null, добавив nullable = false в аннотацию @column. как это
@Column(name = "muColumn", nullable = false)
как избежать свойства null во вставке или обновлении
Ответ 8
Чтобы исключить нулевые значения свойств в hibernate-вставке, используйте атрибут dynamic-insert = true.
1. @org.hibernate.annotations.Entity(dynamicInsert = true) добавьте это в класс
2. В сопоставлении xml используйте атрибут dynamic-insert = true в теге класса.
Ответ 9
Просто оставьте системное_значение из столбцов в инструкции INSERT.
Ответ 10
Я не знаю, как это сделать в JPA.
Но вы можете добавить триггер в базу данных, которая улавливает попытки вставить NULL в соответствующий столбец и перезаписывает вставку для вставки значения по умолчанию? По сути, вы полностью перемещаете поведение по умолчанию в базу данных, а не разделяете его между JPA и базой данных.
Однако, как указывает Берт в своем ответе, это оставило бы объект и базу данных непоследовательными, что почти наверняка плохо.
Ответ 11
вы можете использовать этот способ:
@JoinColumn(name = "team_id", nullable = false)
Используя этот способ, JPA будет проверять значение NULL
.