Избегайте добавлять значения "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;

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