Hibernate SQLQuery обходит кеш сессии Hibernate - PullRequest
4 голосов
/ 21 декабря 2010

Я "транзакционализирую" некоторые обширные манипуляции с базой данных, и я столкнулся с этой проблемой, когда, если я запускаю sql запросы через hibernate, но не использую подход MQL, представление базы данных не выглядит правильным. В частности, в большинстве случаев код использует спящий режим более подходящим образом, но есть места, где кто-то решил просто выполнить sql. Мне не нравится, что они сделали это, но в этот момент «это то, что есть».

Я нашел объяснение , которое, кажется, объясняет это, но все примеры на самом деле получают и управляют транзакцией в коде. Мы используем аннотацию @TransactionAttribute для всего класса, чтобы изменить этот код, и находим множество мест, где такое поведение происходит, но я не совсем уверен, что объяснение применимо к коду, который просто заключен в аннотацию - я предполагал что все, что использует менеджер гибернации, будет полагаться на кэш объектов в сеансе.

Заранее извиняюсь, если я ссылаюсь на понятия в спящем режиме из-за неправильной терминологии и т. Д.

Ответы [ 2 ]

8 голосов
/ 31 мая 2012

На самом деле в блоге «Объяснения» Криса Лэндри не хватает 3 важных API-методов SQLQuery, и именно поэтому у него есть такие проблемы.В частности, (1) addSynchronizedQuerySpace, (2) addSynchronizedEntityName и (3) addSynchronizedEntityClass

Как указывает Партенон, только на основе самой строки SQL-запроса Hibernate не может знать, какие таблицы и / или объекты запрашиваются взапрос.Следовательно, он не знает, какие изменения, поставленные в очередь в сеансе, должны быть сброшены в базу данных.В своем блоге Крис отмечает, что вы можете выполнить вызов flush () самостоятельно, прежде чем выполнять SQL-запрос.Однако то, что я описываю, это возможность автоматического сброса Hibernate.Это фактически делает то же самое для запросов HQL и Criteria.Только там он знает таблицы, на которые влияют.В любом случае, этот процесс автоматической очистки выполняет «минимальную очистку», стирая только те вещи, которые влияют на запрос.Вот где эти методы вступают в игру.

Например, SQL-запрос Чирса:

session.createSqlQuery("select name from user where name = :userName")

На самом деле все, что ему нужно было сделать, это сказать ...

session.createSqlQuery("select name from user where name = :userName")
        .addSynchronizedQuerySpace( "user" )

addSynchronizedQuerySpace( "user" ) говоритHibernate, что запрос использует таблицу с именем "пользователь".Теперь Hibernate может автоматически сбрасывать все ожидающие изменения для сущностей, сопоставленных с этой таблицей пользователей.

7 голосов
/ 21 декабря 2010

Ваш вопрос сбивает с толку, но я предполагаю, что вы говорите, что Hibernate не ищет сущности в кэше сеанса, когда вы выполняете собственные запросы.

SQL Query или Native Query - это запрос, который Hibernate просто передает в базу данных.Hibernate не будет анализировать запрос и не будет анализировать результаты.Hibernate, тем не менее, позволит вам обработать результаты, чтобы преобразовать столбцы в свойства класса.Тем не менее, это звучит вполне естественно, что собственные запросы будут обходить кеш сессии.Это потому, что Hibernate ничего не знает ни о вашем запросе, ни о «результатах» этого запроса (которые на данный момент не являются объектами).

...