Аннулирование сессии JPA EntityManager - PullRequest
8 голосов
/ 08 марта 2010

Проект, над которым я работаю, использует Spring 2.5 и JPA с Hibernate в качестве провайдера.

Мои классы DAO расширяют JpaDaoSupport, поэтому я получаю свой JpaTemplate с помощью метода getJpaTemplate ().

Внутренняя база данных может быть изменена либо моим приложением, либо сторонним приложением.

Когда стороннее приложение изменяет базу данных (в основном, изменения данных конфигурации), мне нужно предоставить пользователю моего приложения способ сделать недействительными все сеансы JPA и перезагрузить новые данные (то есть аннулировать все сеансы спящего режима в фоновом режиме ). Это должно быть «замечено» всеми пользователями моего приложения.

Как я могу это сделать?

Ответы [ 2 ]

22 голосов
/ 08 марта 2010

Есть два уровня кэшей:

  • 1-й уровень - это собственный кеш EntityManager.

    Вы можете либо refresh для одной сущности, и она будет перезагружена из базы данных, либо вы можете clear сам менеджер сущностей, и в этом случае все сущности удаляются из кэша. JPA не может исключить из кэша только одну конкретную сущность . В зависимости от используемой реализации вы можете сделать это, например, Метод Hibernate evict.

  • Кэширование 2-го уровня - это глобальный кеш.

    JPA 1.0 не предоставил поддержку кеша 2-го уровня. Затем вам нужно положиться на базовую конкретную реализацию или отключить ее. JPA 2.0 решит эту проблему с аннотацией @Cache и API кеша. Вы можете очистить кэш 2-го уровня с помощью специфичного для Hibernate API, например, SessionFactory.evict(...).

Дополнительные проблемы с кэшированием:

  • Кэш запросов

    Результат некоторых запросов может быть кэширован. Опять же, не поддерживается в JPA 1.0, но в большинстве реализаций есть способы указать, какой запрос будет кэшироваться и как.

  • Кластеризация

    Затем возникает утомительная проблема синхронизации кэшей между узлами в кластере. В этом случае это в основном зависит от используемой технологии кэширования, например JBoss кеш.

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

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

Но вы также можете отслеживать все открытые сеансы и при необходимости исключать весь кэш 1-го уровня всех открытых сеансов, а также кэш 2-го уровня. Вам все равно нужно было бы управлять синхронизацией самостоятельно, но я думаю, что это возможно.

1 голос
/ 09 марта 2010

С архитектурной точки зрения не очень хорошая идея позволять другому приложению обходить всю вашу бизнес-логику и изменять постоянные данные. Это делает землю под ногами вашего приложения шаткой во многих отношениях:)

Не лучше ли было бы интегрироваться с этой другой системой более элегантным способом, например, с помощью обработки сообщений или пакетной обработки. Spring имеет отличную поддержку для них обоих.

...