Карта / JPA / Hibernate / FetchType, Cascade, состояния entity

FetchType, Cascade, состояния entity

FetchType решает, когда подгружать связанные данные — сразу вместе с основным объектом или только по требованию:

@OneToMany(fetch = FetchType.LAZY)     // подгрузить orders, только когда реально обратишься к ним
private List<Order> orders;

@ManyToOne(fetch = FetchType.EAGER)    // подгрузить user сразу вместе с Order
private User user;

Cascade решает, что делать со связанными объектами при операции над главным, например — удалять ли заказы, если удалили пользователя:

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders;
// userRepository.delete(user) автоматически удалит и все его orders
Копнуть глубже

По умолчанию: @ManyToOne/@OneToOneEAGER, @OneToMany/@ManyToManyLAZY. Это сделано из соображений производительности: подгружать “много” объектов сразу для каждого запроса — дорого (см. тему «Проблема N+1»), поэтому списки по умолчанию ленивые.

Состояния Entity (жизненный цикл объекта в Hibernate):

СостояниеЧто значит
Transientобъект только что создан через new, Hibernate о нём не знает
Managed (Persistent)объект отслеживается Hibernate, изменения автоматически синхронизируются с БД
Detachedобъект больше не отслеживается (например, сессия закрылась), изменения не сохраняются сами
Removedпомечен на удаление, будет удалён при коммите

Главная ловушка с Detached — попытка обратиться к ленивой (LAZY) связи у объекта в состоянии Detached приводит к LazyInitializationException (подробный разбор — отдельная тема «LazyInitializationException»).

🎤 Закрыл тему, если можешь объяснить:
• разницу LAZY и EAGER и что делает CascadeType.ALL;
• четыре состояния entity и чем опасен Detached (если дошёл до 2-го слоя).