Использование JPA 2.0 @ Cacheable в J2SE с Spring, EHCache и Hibernate, без специальных аннотаций Hibernate - PullRequest
2 голосов
/ 14 июля 2011

Я пытаюсь заставить работать кеширование JPA 2.0 в моем приложении Spring 3.0.5, которое использует Hibernate и EhCache. Я не хочу, чтобы мое приложение связывалось с Hibernate и EhCache, и я хочу, чтобы оно использовало чистый JPA-код только настолько, насколько это возможно.

Мне удалось заставить кеширование работать с EHCache и Hibernate, установив специфичную для Hibernate аннотацию @Cache поверх моих классов сущностей и указав org.hibernate.cacheable в качестве подсказки для моих именованных запросов.

Однако, когда я пытаюсь переключить их на @Cacheable(true) и установить подсказку запроса javax.persistence.cache.retrieveMode на "CacheRetrieveMode.USE" (я также пытался просто "USE"), это не работает, и мой именованный запрос, который должен быть кэширован, просто получить снова из базы данных. Я указываю их в аннотации самого NamedQuery, используя hints = ...

Я пробовал различные комбинации <shared-cache-mode>, ENABLE_SELECTIVE, DISABLE_SELECTIVE и т. Д., Но, похоже, ни одна из них не имела никакого эффекта.

Я начинаю подозревать, что эта функция недоступна в J2SE. Я что-то пропустил? Должен ли я включить дополнительный обработчик аннотаций из контекста приложения Spring?

Спасибо.

Ответы [ 3 ]

1 голос
/ 30 марта 2012
  1. Кэширование запросов с помощью Hibernate JPA подразумевает, что это невозможно без подсказки org.hibernate.cacheable до текущей версии 4.1. Конечно, вы можете хранить его в xml-дескрипторах в именованных определениях запросов и изменять его для разных поставщиков JPA (или хранить подсказки для всех вариантов). Но в наших проектах мы реализуем дополнительную утилиту, которая добавляет подсказки к именованному запросу с помощью внешнего конфига (props). Например:

    ru.citc.jpa.queryhint. [Query_name] = org.hibernate.cacheable \ = true, javax.persistence.cache.retrieveMode \ = USE и т. Д. *

  2. Сцепление сущностей может быть настроено внешними свойствами. Смотрите там . Пример:

        <prop key="hibernate.ejb.classcache.ru.citc.migcredit.csrfront.model.Form">read-write,ScriptExecution</prop>
    <prop key="hibernate.ejb.collectioncache.ru.citc.migcredit.csrfront.model.Form.fields">read-write,ScriptExecution</prop>
    <prop key="hibernate.ejb.collectioncache.ru.citc.migcredit.csrfront.model.Form.constraints">read-only,ScriptDesignCollections</prop>
    

В результате мы имеем чистый код JPA с внешней конфигурацией для кэширования и других специфических функций провайдера. Это прекрасно работает для Hibernate и EclipseLink. В качестве дополнительного бонуса у нас есть разные стратегии кэширования для разных модулей приложения (например, веб-приложение администратора не кэширует таблицы метаданных, а веб-приложение оператора кэширует только чтение).

1 голос
/ 01 октября 2013

Похоже, это работает для меня с Hibernate ORM / EhCache 4.2.6. Финал и Spring Framework 3.2.4.RELEASE:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="example.stackoverflow"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false" />
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
            <prop key="javax.persistence.sharedCache.mode">ENABLE_SELECTIVE</prop>
        </props>
    </property>
</bean>

Я аннотировал свой класс Entity с помощью @javax.persistence.Cacheable и вижу, что Hibernate регистрирует SQL-запросы только при получении чего-то, чего нет в кэше. Кажется, ключ использует свойство JPA, чтобы указать, следует ли включать кэш, а не свойство, специфичное для спящего режима.

1 голос
/ 22 июля 2011

Ну, это не чистый JPA, но я использовал аннотацию EhCache для Spring (http://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable), и она отлично работает. Аннотируйте метод DAO, который вы хотите кэшировать с помощью @Cacheable(cacheName="myCache"), настройте кеш в своем Настройка Spring, и смотреть, как исчезают вызовы БД.

...