Что означает FetchType.LAZY в JPA и как он влияет на загрузку связанных сущностей?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
FetchType.LAZY в JPA означает отложенную загрузку связанных сущностей. Вместо загрузки всей связанной коллекции или отдельной сущности при получении основной сущности, JPA создает прокси-объект. Фактическая загрузка данных из базы произойдет только при первом обращении к полям или методам прокси-объекта.
Это позволяет:
- Оптимизировать производительность: Избежать извлечения большого объема данных из базы, когда они не используются.
- Уменьшить потребление памяти: Загружать только необходимые данные.
По умолчанию для большинства связей (@OneToMany, @ManyToMany) используется FetchType.LAZY, а для @OneToOne И @ManyToOne — FetchType.EAGER. Можно явно указать тип загрузки:
// Пример использования FetchType.LAZY
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private Set<ChildEntity> children;
@ManyToOne(fetch = FetchType.LAZY)
private ParentEntity parent;
Проблемы с FetchType.LAZY:
- LazyInitializationException: Может возникнуть, если вы попытаетесь получить доступ к отложенно загруженной сущности после того, как сессия, в которой она была загружена, закрыта.
- N+1 проблема: Если вы итерируете по коллекции сущностей с отложенной загрузкой и обращаетесь к каждой связанной сущности, для каждой сущности коллекции будет выполнен отдельный запрос к базе.
Для решения этих проблем можно использовать:
-
Явное получение связанных данных с помощью
JOIN FETCHв JPQL:// Пример JOIN FETCH SELECT p FROM ParentEntity p JOIN FETCH p.children WHERE p.id = :parentId -
Настройки провайдера JPA (например, использование батчинга).
-
Аннотация
@Fetch(FetchMode.JOIN)или@Fetch(FetchMode.SELECT)в Hibernate.