Ответ
FetchType.LAZY — это стратегия отложенной загрузки, при которой связанная сущность или коллекция загружается из базы данных не сразу, а только при первом прямом обращении к ней. Это оптимизация производительности по умолчанию для ассоциаций @ManyToOne, @OneToMany и @ManyToMany.
Как это работает:
- При загрузке родительской сущности Hibernate создает для lazy-ассоциации прокси-объект или пустую коллекцию-обертку.
- Фактический SQL-запрос для загрузки данных выполняется только при вызове геттера или при попытке обхода коллекции.
Пример с аннотацией:
@Entity
public class Order {
@Id
private Long id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
private List<OrderItem> items; // Коллекция не загрузится сразу
// ...
}
Ключевые моменты и ограничения:
- Требует активного контекста persistence: Обращение к lazy-полю после закрытия сессии Hibernate (
EntityManager/Session) вызоветLazyInitializationException. Работать с такими данными нужно внутри транзакции или с открытой сессией. - N+1 проблема: Неосторожное обращение к коллекциям в цикле может привести к множеству дополнительных запросов. Решается через
JOIN FETCHв JPQL или@EntityGraph. - Не для всех типов: Для
@OneToOneи@ManyToOneпо умолчанию используетсяEAGER, но часто это меняют наLAZY.
Практическое правило: Используйте LAZY для всех ассоциаций и явно загружайте данные с помощью FETCH JOIN только когда они действительно нужны в конкретном сценарии.