Сохранение коллекций базовых типов Hibernate
Для коллекции значений, которые не являются сущностями, используется @ElementCollection.
@ElementCollection
@CollectionTable(
name = "customer_phone",
joinColumns = @JoinColumn(name = "customer_id")
)
@Column(name = "phone", nullable = false)
private Set<String> phones = new HashSet<>();Элементы могут быть простыми типами, enum или @Embeddable.
Модель жизни
Коллекция принадлежит сущности:
- элементы не имеют отдельного
@Id; - не загружаются через собственный репозиторий;
- сохраняются и удаляются вместе с владельцем;
- по стандарту загружаются LAZY.
При изменении списка Hibernate в зависимости от маппинга может удалить и вставить несколько строк вместо точечного update. Большая и часто изменяемая коллекция — кандидат на отдельную entity.
List, Set и Map
Setтребует корректныхequals/hashCodeэлемента и выражает уникальность в модели, но БД также нуждается вUNIQUE;Listбез@OrderColumnне хранит стабильную позицию;@OrderColumnдобавляет индекс позиции, и вставка в начало может обновить много строк;Mapтребует маппинга ключа через@MapKey....
Вопросы для повторения
- Чем
@ElementCollectionотличается от@OneToMany? Элемент — value object без собственной идентичности. - Можно ли сослаться на один элемент из другой сущности? Нет как на самостоятельную entity.
- Почему большая коллекция значений проблемна? Изменение может породить много delete/insert и раздувать граф владельца.
- Гарантирует ли
Setуникальность в БД? Нет, нужно ограничение схемы.
Связано: Встраиваемый класс Embeddable, Fetch type Hibernate, Связи таблиц.