Hibernate/JPA: Встраиваемый инициализируется, если все свойства являются пустыми или пустыми

#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.