Ответ
JOIN FETCH в JPQL-запросе JPA/Hibernate принудительно использует жадную загрузку (Eager Loading) для указанных связанных коллекций или сущностей в рамках этого конкретного запроса.
Как это работает:
Hibernate формирует один SQL-запрос с JOIN, чтобы сразу загрузить основную сущность и связанные данные, избегая проблемы N+1, даже если для ассоциации установлена ленивая загрузка (FetchType.LAZY).
Пример:
@Entity
public class Order {
@Id
private Long id;
// По умолчанию или явно LAZY
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
private List<OrderItem> items;
}
// JPQL-запрос с JOIN FETCH
String jpql = "SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id";
Order order = entityManager.createQuery(jpql, Order.class)
.setParameter("id", 1L)
.getSingleResult();
// Коллекция items загружена немедленно в этом запросе
Важно: JOIN FETCH переопределяет стратегию загрузки, указанную в аннотации (LAZY/EAGER), только для данного запроса. Вне этого запроса ассоциация продолжает вести себя согласно своей аннотации.