Проверяет умение оптимизировать загрузку данных в ORM.
N+1 возникает, когда для каждой из N сущностей выполняется отдельный запрос за связанными данными. Решения:
JOIN FETCH в JPQL.
EntityGraph.
BatchSize для пакетной загрузки.
Пример проблемы:
List<Author> authors = authorRepository.findAll(); // 1 запрос: SELECT * FROM author
authors.forEach(author -> {
author.getBooks().size(); // N запросов: SELECT * FROM book WHERE author_id = ?
});Способы решения:
JPQL с JOIN FETCH:
@Query("SELECT a FROM Author a JOIN FETCH a.books")
List<Author> findAllWithBooks();Плюсы: Один запрос, данные загружаются сразу.
Минусы: Риск дублирования данных (например, если у автора 100 книг, его данные повторятся 100 раз).
EntityGraph:
@EntityGraph(attributePaths = "books")
List<Author> findAll();Генерирует LEFT OUTER JOIN.
@BatchSize:
@Entity
public class Author {
@OneToMany(fetch = LAZY)
@BatchSize(size = 10) // Загружает книги пачками по 10 авторов
private List<Book> books;
}Запрос: SELECT * FROM book WHERE author_id IN (?, ?, ...).
Вывод: Используйте JOIN FETCH для точечных запросов, BatchSize — для глобальной оптимизации.