Выбор ответа Middle Hibernate: N+1, lazy, кеш обновлено

Кеш первого уровня

Вопрос

В одной транзакции дважды вызвали em.find(User.class, 1L). Сколько SELECT выполнится и что вернётся?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Один SELECT; оба вызова вернут один и тот же объект. Контекст персистентности хранит загруженные сущности по id (identity map): второй find берёт объект из него без запроса.

Варианты ответа

  1. Два SELECT и два разных объекта
  2. Ноль: кеш первого уровня заполняется при старте приложения
  3. Один SELECT; оба вызова вернут один и тот же объектправильный ответ
  4. Один SELECT, но два разных объекта с одинаковыми данными

Разбор

Контекст персистентности хранит загруженные сущности по id (identity map): второй find берёт объект из него без запроса. Это гарантирует, что в рамках транзакции одна запись представлена одним объектом. Заранее при старте ничего не загружается. JPQL-запрос, в отличие от find, всё равно пойдёт в базу, но вернёт уже управляемые экземпляры.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.