С какими сложностями или проблемами сталкивались при работе с Hibernate
Что проверяют
Работали ли вы с Hibernate руками или только расставляли аннотации по туториалу. Интервьюер ждёт узнаваемых проблем и того, как вы их находили и чинили. Следом почти всегда просят объяснить N+1 или разницу между LAZY и EAGER на вашем примере.
Как отвечать
Это вопрос про опыт, поэтому стройте ответ на своих случаях: что сломалось, как заметили, что сделали, чем подтвердили результат. Цифры берите из своих логов и замеров, а не круглые проценты. Типичные темы:
- N+1 запросов: список сущностей тянет связи по одной. Лечится
JOIN FETCHв JPQL,@EntityGraphв Spring Data или@BatchSizeна коллекции; LazyInitializationException: обращение к ленивой связи после закрытия сессии. Выход в том, чтобы загрузить нужное внутри транзакции или отдать DTO-проекцию, а не включатьEAGERилиspring.jpa.open-in-view(в Spring Boot он включён по умолчанию);MultipleBagFetchException: попытка зафетчить две коллекции типаListодним запросом. Решается разнесением на два запроса, замена наSetубирает исключение, но оставляет декартово произведение;- dirty checking и flush: изменённая управляемая сущность уйдёт в базу без явного
save, а автоматический flush перед запросом меняет порядок операций; - кэш второго уровня: в Hibernate 6 подключается через JCache (
hibernate-jcacheплюс Ehcache 3 или Caffeine), старого модуляhibernate-ehcacheбольше нет. Кэшировать стоит редко меняющиеся справочники.
Как вы нашли проблему, важно не меньше решения: hibernate.generate_statistics, логирование SQL с параметрами, datasource-proxy или p6spy, счётчик запросов в тесте.
Если серьёзных проблем не было, так и скажите и разберите одну из тем выше как то, что проверили бы первым делом.
Где спотыкаются
Рассказывают шаблонную историю «ускорили на 30%» без механизма: какой был запрос, сколько их было до и после.
Лечат LazyInitializationException через FetchType.EAGER. Исключение уходит, а на его месте появляются лишние джойны и тот же N+1 в других местах.
Путают кэш первого уровня, который живёт в рамках сессии и есть всегда, с кэшем второго уровня, который включается и настраивается отдельно.