Ответ
FetchType.LAZY — это стратегия ленивой загрузки, при которой связанные сущности загружаются из базы данных только при первом прямом обращении к ним, а не сразу при загрузке родительской сущности.
Основные характеристики:
- Используется по умолчанию для ассоциаций
@OneToManyи@ManyToMany. - Цель — оптимизация производительности, чтобы избежать загрузки ненужных данных и лишних JOIN-запросов.
Пример объявления:
@Entity
public class Order {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
private List<OrderItem> items;
// ...
}
Ключевая проблема — LazyInitializationException:
Исключение возникает при попытке доступа к ленивой коллекции или прокси-объекту вне контекста открытой сессии Hibernate (например, после возврата из метода @Transactional или закрытия EntityManager).
Способы решения:
- Управление контекстом: Обеспечить открытую сессию в месте обращения (аннотация
@Transactionalв сервисном слое). - Явная инициализация: Использовать
Hibernate.initialize(collection)до закрытия сессии. - JOIN FETCH в запросе: Использовать
JOIN FETCHв JPQL или Criteria API для единовременной загрузки связанных данных.@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id") Order findOrderWithItems(@Param("id") Long id); - Entity Graphs: Использовать
@EntityGraphдля определения графа загружаемых атрибутов.
Важно: Слепое использование FetchType.EAGER часто приводит к проблеме N+1 select и снижению производительности.