#java #hibernate #jpa
Вопрос:
Я использую режим гибернации и имею следующую модель JPA:
@Entity
public class MyEntity {
@Embedded
MyEmbeddable embedded;
}
@Embeddable
public class MyEmbeddable {
@Column
private String name;
@ElementCollection
@Enumerated(EnumType.STRING)
@Size(min = 1)
private Set<MyEnum> usage;
@NotNull
private LocalDate localDate;
}
MyEntity может содержать MyEmbeddable, но все встраиваемое должно быть необязательным. Поэтому я бы предпочел, чтобы это MyEntity.embedded
было null
, когда все свойства MyEmbeddable
пусты или равны нулю.
Однако, когда я читаю такую сущность из БД, Hibernate инициализируется embedded
как non-null
— что приводит к ошибкам ограничений, когда сущность снова сбрасывается в базу данных.
В качестве обходного пути мне пришлось бы написать некоторый код для null
embedded
свойства перед сбросом/сохранением, что кажется мне очень плохой идеей.
Я подозреваю, что коллекция элементов вызывает такое поведение инициализации — потому что в соответствии со спецификацией JPA коллекции элементов всегда инициализируются empty
(не являются нулевыми).
Есть какие-нибудь идеи/подсказки, как вы можете сказать, чтобы Hibernate embedded
вообще не инициализировался?
Комментарии:
1. вы определяете сеттер и добавляете туда свою логику, проверяете, не является ли объект null и что-то в этом роде,
embedded.isValid()
и устанавливаете embedded как null, если он недействителен.
Ответ №1:
Вы уверены, что все встроенные значения столбцов равны нулю? localDate
аннотируется NotNull
, поэтому я думаю, что это проблема, препятствующая тому, чтобы встроенное свойство было пустым. Кроме того, @Size(min = 1)
на съемочной площадке похоже, что это тоже может быть проблемой.
Обратите внимание, что режим гибернации предоставляет возможность управления этим поведением (https://in.relation.to/2016/02/10/hibernate-orm-510-final-release/):
Исторически сложилось так, что Hibernate всегда обрабатывал бы все значения столбца null для @Embeddable, чтобы означать, что @Embeddable сам должен быть равен нулю. 5.1 позволяет приложениям указывать, что Hibernate должен вместо этого использовать пустой экземпляр @Embeddable. Это достигается с помощью настройки регистрации:
hibernate.create_empty_composites.enabled
.Подробнее см. HHH-7610.