Добавить в корзинуПозвонить
Найти в Дзене
Java

N+1 в Spring Boot выглядит безобидно, пока прод не начинает молиться на базу данных

Классический сценарий: Вы грузите список заказов: orderRepository.findAll() А потом в цикле обращаетесь к order.getItems(). Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items. 100 заказов = 101 SQL-запрос. И вот здесь спасает @EntityGraph. Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу: @EntityGraph(attributePaths = {"items"}) В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу. Что получаем: - меньше SQL-запросов - меньше нагрузки на БД - чище код репозитория - без ручного JPQL - fetch-стратегия управляется точечно под конкретный кейс LAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает. @EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.

N+1 в Spring Boot выглядит безобидно, пока прод не начинает молиться на базу данных.

Классический сценарий:

Вы грузите список заказов:

orderRepository.findAll()

А потом в цикле обращаетесь к order.getItems().

Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items.

100 заказов = 101 SQL-запрос.

И вот здесь спасает @EntityGraph.

Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу:

@EntityGraph(attributePaths = {"items"})

В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу.

Что получаем:

- меньше SQL-запросов

- меньше нагрузки на БД

- чище код репозитория

- без ручного JPQL

- fetch-стратегия управляется точечно под конкретный кейс

LAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает.

@EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.