2009-06-17 5 views
3

Я использую РАСШИРЕННЫЙ Постоянный контекст, потому что это позволит мне лениво загружать отношения одного объекта на объект, а также не будет требовать SELECT, прежде чем «слить» объект с постоянным контекстом.JPA/Hibernate Query возвращает исходные результаты

У меня есть DummyObject с:

  1. A "Последнее обновление" Дата Поле

  2. A One-многим

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

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

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

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

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

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

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

  1. изменить PersistentContextType к TRANSACTIONAL (то, что не позволит мне лениво загрузите ONE МНОГО отношения)

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

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

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

Может быть, я не понимаю "РАСПРОСТРАНЕНИЯ" против TRANSACTIONAL правильно.

+1

Последнее обновление отображается как версия? – Surya

+0

Просто попробовал это. Не работает. Я также попытался добавить явное поле «версия» и аннотировать его с помощью @Version. И не работал. – systemoutprintln

+0

is equals и hashcode, смотрящий lastUpdated? вы видите дополнительные объекты, которые не входят в результат em.createQuery()? – zmf

ответ

0

Вы пробовали делать флеш() перед приемом?

+0

Просто попробовал ... Не работал. Спасибо хоть. – systemoutprintln

+0

Вы повторно извлекаете объект каждый раз или используете ленивую загруженную ссылку? У меня возникли проблемы, когда объект должен был появиться снова до появления новых данных. – Jesse

+0

Я не уверен, понимаю ли вы, что вы имеете в виду. Я выполняю запрос выше каждые 5 секунд, и результаты, полученные из этого Запроса, являются устаревшими. Это скорее «тестовый» случай, чем реальная реализация. В принципе, моя проблема заключается в том, что я хочу иметь возможность использовать расширенный тип контекста и быть в состоянии лениво загружать отношения. Но то, что не работает, заключается в том, что Query всегда возвращает устаревшие результаты. – systemoutprintln

0

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

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

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

+0

Да, я посмотрел на итерацию по возвращенному набору результатов и выполнению «обновления» для каждого объекта, но это смешно с большими наборами результатов. – systemoutprintln

+0

Сохраняется ли содержание списка (т. Е. Не будут ли вы получать новые объекты или удалены старые объекты)? –

+0

Содержимое списка остается таким же, если я не обновляю() для каждого объекта в списке. – systemoutprintln

1

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