Как я решал проблему N+1 в Hibernate

Разрабатывал Spring Boot-приложение с сущностями Task и TaskDetail (одна задача → много деталей). Столкнулся с классической проблемой N+1 запросов, когда пытался загружать данные.

Как проявлялась проблема

Было 2 сценария: 1. Простой список задач (без деталей) - для табличного отображения 2. Полная задача со всеми деталями - для детальной страницы

Наивная реализация: @Entity public class Task { @Id private Long id;

@OneToMany(mappedBy = "task", fetch = FetchType.LAZY) private List<TaskDetail> details; }

Когда делал так: List<Task> tasks = taskRepository.findAll(); tasks.forEach(task -> { System.out.println(task.getDetails().size()); });

В логах Hibernate (spring.jpa.show-sql=true) видел: Hibernate: select t1_0.id from task t1_0 Hibernate: select d1_0.task_id from task_detail d1_0 where d1_0.task_id=? Hibernate: select d1_0.task_id from task_detail d1_0 where d1_0.task_id=? ... и так для каждой задачи

Для 100 задач → 101 запрос

Как исправил (3 способа)

1. @EntityGraph - точечная жадная загрузка

После изучения проблемы пришел к выводу: - Все ассоциации всегда должны быть LAZY - Жадная загрузка только через @EntityGraph когда действительно нужно

public interface TaskRepository extends JpaRepository<Task, Long> {

List<Task> findAll();

@EntityGraph(attributePaths = "details") List<Task> findAllWithDetails(); }

Как работает @EntityGraph: - Превращает LAZY-ассоциации в FETCH для конкретного запроса - Генерирует LEFT OUTER JOIN - Не влияет на другие методы репозитория

Главные выводы

1. Все ассоциации делаем LAZY по умолчанию 2. Жадная загрузка только через @EntityGraph когда точно нужно 3. JOIN FETCH для сложных кастомных запросов 4. BatchSize как компромисс для ленивой загрузки

repost

33

input message

напишите коммент

еще контент автора

еще контент автора

войдите, чтобы увидеть

и подписаться на интересных профи

в приложении больше возможностей

пока в веб-версии есть не всё — мы вовсю работаем над ней

сетка — cоциальная сеть для нетворкинга от hh.ru

пересекайтесь с теми, кто повлияет на ваш профессиональный путь