Повторный JEE JPA набирал запросы, всегда отправляющиеся в БД... Путаница кеша первого уровня

63
5

Я думал, что у меня довольно четкое понимание кеша 1-го уровня JPA. Тем не менее, при тестировании моего бина JEE Msg (JBOSS JPA 2.0) с соответствующим параметром файла persistence.xml "hibernate.show_sql" установлено значение true, я вижу поведение sql, которое я не знаю, как смириться. Вот фрагмент моего кода:

logger.info("Getting widget by query. Sql should be issued");
TypedQuery<Widget> query = entityManager.createQuery("SELECT w FROM Widget w WHERE w.widgetId = :id", Widget.class);
query.setParameter("id", 1);
// This should go to the db
Widget widget = query.getSingleResult();

logger.info("Getting widget by query again. No sql should be issued");
TypedQuery<Widget> query2 = entityManager.createQuery("SELECT w FROM Widget w WHERE w.widgetId = :id", Widget.class);
query2.setParameter("id", 1);

Widget widget2 = query2.getSingleResult();

logger.info("Getting widget by entity manager find. No sql should be issued");
entityManager.find(Widget.class, 1);

Из вышесказанного я ожидаю, что в журнале регистрируется 1 оператор выбора базы данных, но я вижу, что это оператор select для обоих операторов getSingleResult(), что меня смущает. Может ли кто-нибудь объяснить это? Обратите внимание, что поиск не приводит к заявлению о регистрации sql. Кроме того, я заметил, что если я не помещаю предложение Where в вышеприведенные операторы createQuery и изменяю инструкции getSingleResult() на операторы getResultList(), их выполнение также приводит к двум операторам Select, поступающим в базу данных. Я проверил это с помощью журнала hibernate и сеанса отладки, где я вставил строку между первым и вторым оператором, используя sqlplus. Что касается createQuery() и где клаузулы не должны быть менеджерами сущностей достаточно умными, чтобы знать, что они уже загрузили результаты данного запроса? В предыдущем примере менеджеру сущности не следует понимать, что он уже загрузил все объекты Widget? Обратите внимание: когда я просматриваю объекты и выполняю проверки равенства, менеджер объектов управляет ими соответствующим образом (т.е. Нет двух объектов, относящихся к одной и той же строке таблицы db).

спросил(а) 2021-01-28T00:40:02+03:00 4 месяца, 3 недели назад
1
1 ответ
-4

Кэширование запросов (в отличие от кэширования объектов) по умолчанию не включено. Вам нужно использовать соответствующий запрос (@QueryHint(name="org.hibernate.cacheable",value="true") или query.setHint("org.hibernate.cacheable", true)).

(Я, конечно, молча предполагаю, что вы установили для свойства hibernate.cache.use_query_cache значение true в persistence.xml)

Предупреждение: слишком много полагается на кеширование запросов, что может привести к обнаружению ошибок с ошибками (поэтому JPA достаточно умен, чтобы не включать его по умолчанию). Обязательно просмотрите соответствующие документы (например, https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch06.html) о том, как правильно обращаться с ним.

ответил(а) 2021-01-28T00:40:02+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема