Обновляет ли HQL кэш 2-го уровня? - PullRequest
16 голосов
/ 23 мая 2011

Собственные запросы очищают записи кэша 2-го уровня. Ответ от форума hibernate, которому 7 лет, говорит, что запросы на обновление HQL также очищают кэш 2-го уровня. Но так ли это до сих пор?

Поскольку HQL-запрос содержит точные поля, которые необходимо обновить, и в какой сущности, я думаю, что не должно быть так сложно вести себя, как если бы вызывался обычный session.save(..).

Ответы [ 3 ]

11 голосов
/ 18 января 2013

Собственные запросы очищают записи кэша 2-го уровня.

  1. Собственные запросы (на самом деле это только для собственных вставок / удалений / обновлений, а не запросов) делают недействительными записи кэша 2-го уровня для всех кэшей (WHOLE CACHE). Я подтвердил это с текущей стабильной версией Hibernate: 4.1.9. Это разумно, потому что Hiberante не может знать, что было изменено в БД, поэтому единственный вариант - аннулировать весь кэш 2-го уровня. Это может быть серьезной проблемой в некоторых системах, которые сильно зависят от кэша 2-го уровня.

Хотя есть возможность указать, что из кэша 2-го уровня следует сделать недействительным (или даже указать, что из кэша ничего не удаляется). Посмотрите на отличный пост в блоге http://www.link -intersystems.com / bin / view / Blog / Hibernate% 27s + второй + уровень + кэш + и + нативные + запросы , где это подробно объясняется.

Чтобы запретить Hibernate что-либо из кэша сделать недействительным:

SQLQuery sqlQuery = session.createSQLQuery("ALTER SESSION SET NLS_COMP = 'BINARY'");
sqlQuery.addSynchronizedQuerySpace("");  
int updatedEntities = sqlQuery.executeUpdate();

Чтобы дать Hibernate команду аннулировать только кэш сущностей Person:

SQLQuery sqlQuery = session.createSQLQuery("UPDATE PERSON SET ... WHERE ...");
sqlQuery.addSynchronizedEntityClass(Person.class);
int updatedEntities = sqlQuery.executeUpdate();

В ответе на спящем форуме, которому 7 лет, сказано, что HQL Запросы на обновление также очищают кэш 2-го уровня. Но так ли это до сих пор?

  1. HQL делает недействительной только область кэша 2-го уровня, которая связана с сущностью, для которой вы выполняете некоторые вставки / обновления / удаления. Это имеет смысл, поскольку Hibernate знает, на какие объекты влияет HQL, он может очистить только область кэша 2-го уровня для этой сущности.

Пример:

entityManager.createQuery("delete from Person p where p.id = 1").executeUpdate();

Это сделает недействительным "только" кеш сущности Person.

Мне неизвестна какая-либо возможность запретить Hibernate аннулировать кэш 2-го уровня для конкретной сущности, когда речь идет о HQL.

1 голос
/ 26 мая 2011

Мы видели, как обновление HQL очищало кэш 2-го уровня при работе с Hibernate 3.2.x

. В качестве простого способа проверки вашей индивидуальной настройки реализовано что-то вроде:

http://narcanti.keyboardsamurais.de/hibernate-statistics-jsp-reloaded.html

Обратите внимание на детали на этой странице до и после выполнения транзакции обновления HQL ...

Или собирайте статистику непосредственно в своем коде и / или используя JMX

http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-monitoring

Что касается улучшенного поведения, проект Hibernate может быть открыт для реализации патча:)

0 голосов
/ 24 мая 2011

Самое близкое, что я мог выкопать, было это: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache

Я бы предположил, что это во многом связано с тем, какого провайдера вы используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...