JPA / Hibernate Query возвращает устаревшие результаты - PullRequest
3 голосов
/ 17 июня 2009

Я использую EXTENDED Постоянный контекст, потому что это позволит мне лениво загрузить отношение «один-много» для объекта, а также не потребует SELECT, прежде чем я «сливаю» объект с постоянный контекст.

У меня есть объект DummyObject с:

  1. Поле даты «Последнее обновление»

  2. Отношение один-много

Этот объект обновляется каждые 5 секунд в одной JVM через em.merge(DummyObject) вызов.

В другой JVM я запрашиваю, чтобы DummyObject выполнял вызов, подобный следующему

em.createQuery("from DummyObject").getResultList();  

Я также делаю этот запрос каждые 5 секунд.

Проблема заключается в том, что все объекты, полученные в результате запроса, имеют метку времени самого первого запроса после последовательных вызовов, даже если Hibernate генерирует правильный оператор SQL (когда я выполняю вход оператора), а база данных получать обновления правильно (я подтвердил).

Я также попробовал все виды оптимистической блокировки с @Version безрезультатно. (См. Комментарии)

Другое дело, что это работает правильно, когда:

  1. Я изменяю PersistentContextType на Транзакции (то, что не позволит мне лениво загрузить ОДНО-МНОЖЕСТВО отношений)

  2. Я делаю вызов EntityManager.clear () прежде чем я сделаю запрос выше (То, что тоже не позволит мне лениво загрузить ОДНОМНОГО отношения).

Почему мой запрос возвращает устаревшие данные? У меня нет Кэширование второго уровня или кеширование запросов включено.

Я что-то не так делаю? Есть ли что-то, что я могу установить с помощью query.setHint (,)?

Может быть, я не понимаю " EXTENDED " против TRANSACTIONAL правильно.

Ответы [ 3 ]

1 голос
/ 22 июня 2009

Сеанс гибернации кэширует постоянные объекты. Так как вы изменяете в одной JVM (A) и читаете в другой JVM (B), сеансы B необходимо обновить, чтобы увидеть изменения. Вы можете открыть новый сеанс или удалить / обновить постоянные объекты. Вы также можете реплицировать сеансы в обеих виртуальных машинах Java, которые могут решить вашу проблему. Или вы можете попытаться изменить запрос, чтобы он возвращал только те части «DummyObject», которые вам нужны, и считывал постоянный объект только тогда, когда это необходимо. Вы также можете попробовать сеанс без сохранения состояния.

0 голосов
/ 19 июня 2009

Интересно. Мне кажется, что экземпляр сущности в вашем контексте постоянства не обновляется с результатами запроса. Это может быть сделано специально - вы можете случайно перезаписать локальные изменения, выполнив запрос.

Что еще хуже, в JPA нет способа отсоединить один экземпляр. Вы либо очищаете весь контекст, либо нет. Так что это тоже не возможное решение.

В классе PersistanceContext доступен метод refresh(), который извлекает изменения из базы данных и соответствующим образом обновляет экземпляр сущности. Но я вижу, как это не может быть применимо в реальной реализации. Так что мой ответ оказывается: вы, вероятно, не можете заставить его работать.

0 голосов
/ 18 июня 2009

Вы пытались выполнить сброс () до получения?

...