Избегайте вставки нулевых значений в таблицу базы данных через JPA - PullRequest
17 голосов
/ 22 декабря 2010

я начинаю с JPA2 и чувствую себя довольно комфортно.Но у меня есть проблема при сохранении сущностей со значениями свойства NULL для полей базы данных NON 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 для исключения нулевых свойств из оператора SQL INSERT.

Я хочу иметь возможность установить 'system_time' в моем объекте или позволить ему иметь значение 'null' и позволить базе данных установить значение по умолчаниюзначение.

Любая помощь приветствуется!

Regads Klaus

Ответы [ 10 ]

20 голосов
/ 23 декабря 2010

Использование аннотации

@Column(insertable = false)

предотвратит создание значения в sql.

17 голосов
/ 23 декабря 2010

Я бы не стал полагаться на значения по умолчанию в базе данных в сочетании с JPA. Вы должны будете прочитать сущность обратно после вставки, иначе у вас будет несоответствие между состоянием сущности и состоянием БД.

Выберите здесь прагматический подход и инициализируйте все значения в Java. Никогда не слышал о способе сказать JPA / Hibernate об исключении пустых значений при вставке / обновлении.

6 голосов
/ 16 апреля 2013

В аннотации @ Column установите для атрибута вставляемый значение false, как это:

`@Column(name="system_time", <b>insertable = false</b>)`

Или, если необходимо проверить, когдазначение NULL, затем сделайте триггер ДО ВСТАВКИ на таблицу.

2 голосов
/ 22 декабря 2010

Из документации: 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();

Таким образом, по умолчанию текущая дата будет вставлена, если вы ее не установите.

1 голос
/ 30 августа 2018

Я нашел простое решение: определить значение по умолчанию в pojo.

@Column(name="system_time")
private Date systemTime = new Date();
0 голосов
/ 21 января 2018

вы можете избежать использования свойства null, добавив nullable = false к аннотации @column. как это

@Column(name = "muColumn", nullable = false)

как избежать использования свойства null при вставке или обновлении

0 голосов
/ 16 февраля 2017

Я использую это (для базы данных Oracle):

@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATION_TIME", 
        columnDefinition="TIMESTAMP DEFAULT SYSTIMESTAMP",
        nullable=false,
        insertable=false,
        updatable=false)
private Date creationTime;
0 голосов
/ 17 июля 2011

вы можете использовать этот способ:

@JoinColumn(name = "team_id", nullable = false)

Используя этот способ, JPA будет проверять значение NULL.

0 голосов
/ 24 декабря 2010

Я не знаю ни одного способа сделать это в JPA.

Но вы можете добавить триггер в базу данных, который отлавливает попытки вставить NULL в рассматриваемый столбец и переписывает вставку для вставкипо умолчанию?По сути, вы перемещаете поведение генерации по умолчанию полностью вниз в базу данных, а не разделяете его между JPA и базой данных.

Однако, как указывает Берт в своем ответе, это приведет к несовместимости объекта и базы данных., что почти наверняка плохо думать.

0 голосов
/ 22 декабря 2010

Просто опустите system_time из столбцов в инструкции INSERT.

...