У меня есть атрибут в моем Java-объекте:
@Basic(fetch = FetchType.LAZY) //I tried without this as well
@Column(name = "value_x", columnDefinition = "bigint default 0")
private Long valueX;
В определении таблицы в pgAdmin я вижу:
value_x bigint DEFAULT 0,
но когда объект вставлен (с этим атрибутом как null), столбец пуст / null без вставленного значения 0.
Кто-нибудь знает, почему он не вставляет значение по умолчанию? Используя EclipseLink.





Нулевое значение связано с тем, что JPA явно вставляет значение null в этот столбец, если не реализована специальная обработка. columnDefinition действительно создает столбец с помощью DEFAULT, но он не заставляет JPA узнавать / или подчиняться ему впоследствии.
И это столбец, допускающий значение NULL, поэтому ошибки нет. Посмотрите, что происходит в простом SQL, подумайте об этой таблице:
create table example (
col1 bigint default 42,
col2 bigint default 99
);
Затем сделайте вставку типа:
insert into example (col1) values (null);
затем выбрав:
select * from example;
покажет результат вроде:
col1 | col2
------+------
(null) | 99
Если вам нужно управлять значениями по умолчанию на стороне Java, вам понадобятся некоторые специальные вещи на стороне Java.
См., Например, этот вопрос и обратите внимание, что принятый ответ не рабочий, а этот ответ. Итак, установив значение при создании экземпляра класса:
private Long valueX = 0;
Другой способ - это, как предлагает этот ответ на другой вопрос, с использованием @PrePersist:
@PrePersist
void prePersist() {
if (this.valueX == null)
this.valueX = 0;
}
Спасибо, это работает, если я правильно понимаю, что эти два решения дают одинаковый результат? (проверено и, похоже, ведет себя так же)
да. Единственное отличие состоит в том, что @PrePersist представляет собой инициализацию ленивый, она выполняется непосредственно перед сохранением в JPA. Это может зависеть от случая, какой из них более подходит.
Я пошел с простой установкой значения, так как оно чище, но в случае одновременного создания огромного количества записей, которые сохраняются в разное время (а атрибут может быть чем-то большим), я вижу преимущество в prePersist.
Я нашел другой способ решить ту же проблему, потому что, когда я создаю свой собственный объект и сохраняю его в базе данных, я не соблюдал DDL со значением по умолчанию.
Итак, я посмотрел на свою консоль, и сгенерировал SQL, и увидел, что вставка идет со всеми полями, но только одно свойство в моем объекте изменило значение.
Я поместил эту аннотацию в класс модели.
@DynamicInsert
При вставке данных платформа не вставляет нулевые значения или значения, которые не изменяются, что делает вставку короче.
Также есть аннотация @DynamicUpdate.
Поставщик JPA не использует значение по умолчанию, кроме как при создании таблицы. Если вы хотите, чтобы туда поместили 0, установите это поле в своем классе