Выбор ответа Middle Hibernate: N+1, lazy, кеш обновлено
Кеш первого уровня
Вопрос
В одной транзакции дважды вызвали em.find(User.class, 1L). Сколько SELECT выполнится и что вернётся?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Один SELECT; оба вызова вернут один и тот же объект. Контекст персистентности хранит загруженные сущности по id (identity map): второй find берёт объект из него без запроса.
Варианты ответа
- Два SELECT и два разных объекта
- Ноль: кеш первого уровня заполняется при старте приложения
- Один SELECT; оба вызова вернут один и тот же объектправильный ответ
- Один SELECT, но два разных объекта с одинаковыми данными
Разбор
Контекст персистентности хранит загруженные сущности по id (identity map): второй find берёт объект из него без запроса. Это гарантирует, что в рамках транзакции одна запись представлена одним объектом. Заранее при старте ничего не загружается. JPQL-запрос, в отличие от find, всё равно пойдёт в базу, но вернёт уже управляемые экземпляры.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.