Вопрос с собеседования · Базы данных

Почему возникает LazyInitializationException в Hibernate и как его правильно лечить?

MiddleORM и N+1Hibernate / JPASpring Data
Ещё спрашивают так:
  • Почему падает LazyInitializationException?
  • Что такое Open Session in View?
Коротко

Ленивую связь трогают после закрытия сессии (вне транзакции, в контроллере или сериализаторе) — прокси не может выполнить запрос и бросает исключение.

  • Правильно: загрузить нужное заранее — JOIN FETCH, @EntityGraph, DTO-проекция
  • Open Session in View «лечит» ценой запросов из слоя представления и N+1
  • Включение EAGER — плохое лечение: грузит лишнее всегда

А ещё В Spring Boot spring.jpa.open-in-view по умолчанию true с предупреждением — лучше выключить

Подробно

Lazy-связь Hibernate отдаёт как proxy и грузит при первом обращении — но только пока открыта persistence-сессия. Если обратиться к ней уже после коммита/закрытия сессии (например, в контроллере/сериализаторе), proxy не может выполнить запрос и бросает LazyInitializationException. Правильное лечение — заранее загрузить ровно нужные связи в запросе через JOIN FETCH или @EntityGraph, либо вернуть DTO-проекцию с нужными полями. Антипаттерны: глобальный EAGER (тянет лишнее во всех сценариях и плодит запросы) и Open Session In View (держит сессию открытой на весь HTTP-запрос — маскирует проблему и провоцирует N+1 в слое представления).

Что хотят услышать

  • Причина: сессия закрыта, прокси не загрузить.
  • Правильные решения: загрузка в запросе, DTO.
  • Почему OSIV и EAGER — плохие решения.

Частые ошибки

  • Чинить глобальным EAGER.
  • Полагаться на Open-Session-In-View вместо явной загрузки связей.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Связь помечена EAGER и грузится слишком рано; лечат переводом в LAZY
  • ✗База недоступна на момент старта приложения
  • ✗Сущность не имеет первичного ключа
  • ✓Lazy-связь трогают вне открытой сессии; лечат JOIN FETCH, EntityGraph или DTO-проекцией

Что спросят дальше

  • Чем @EntityGraph отличается от JOIN FETCH?
  • Почему Open Session In View считают антипаттерном?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования