Ответ
Да, может. Проблема N+1 запроса связана не с типом загрузки (LAZY или EAGER), а с способом выполнения загрузки связанных коллекций.
Как возникает проблема при FetchType.EAGER:
- Hibernate выполняет один запрос для получения всех сущностей
Parent. - Для каждого загруженного
Parentон немедленно (из-заEAGER) выполняет отдельныйSELECTдля загрузки его коллекцииchildren.
Пример сущности и проблемного запроса:
@Entity
public class Parent {
@Id private Long id;
@OneToMany(fetch = FetchType.EAGER) // EAGER-загрузка
private List<Child> children;
}
// Запрос, вызывающий N+1:
List<Parent> parents = em.createQuery("SELECT p FROM Parent p", Parent.class)
.getResultList();
Это приведет к выполнению: 1 запрос (для всех Parent) + N запросов (для children каждого Parent).
Решение: Использовать JOIN FETCH в JPQL-запросе, который загружает данные за один SQL-запрос с JOIN.
List<Parent> parents = em.createQuery(
"SELECT DISTINCT p FROM Parent p JOIN FETCH p.children", Parent.class)
.getResultList();
Вывод: Стратегия EAGER не решает проблему N+1, а лишь меняет момент ее возникновения (с отложенного до немедленного). Для эффективной загрузки всегда нужно явно указывать JOIN FETCH или использовать @EntityGraph.