在J2SE中使用JPA 2.0 @Cacheable与Spring,EHCache和Hibernate,没有Hibernate特定的注释

时间:2011-07-13 22:11:38

标签: hibernate spring caching jpa-2.0 ehcache

我正在尝试使用Hibernate和EhCache在我的Spring 3.0.5应用程序中运行JPA 2.0 Caching。我不希望我的应用程序绑定到Hibernate和EhCache,并希望尽可能使用纯JPA代码。

我设法通过在我的实体类之上设置Hibernate特定的@Cache注释并指定org.hibernate.cacheable作为我的命名查询的查询提示来使用EHCache和Hibernate进行缓存。

但是,当我尝试将这些内容切换为@Cacheable(true)并将查询提示javax.persistence.cache.retrieveMode设置为"CacheRetrieveMode.USE"时(我也只尝试了"USE"),它无效我的命名查询应该被缓存,只是从数据库中再次检索。我使用hints = ...

在NamedQuery本身的注释中指定这些

我尝试了<shared-cache-mode>ENABLE_SELECTIVEDISABLE_SELECTIVE等的各种组合,但似乎没有任何效果。

我开始怀疑J2SE上没有此功能。我错过了什么吗?我应该从Spring应用程序上下文中启用一些额外的注释处理程序吗?

感谢。

3 个答案:

答案 0 :(得分:1)

嗯,它不是纯粹的JPA,但是我已经使用了Spring的EhCache注释(http://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable)并且效果很好。使用@Cacheable(cacheName="myCache")注释要缓存的DAO方法,在Spring配置中配置缓存,并观察数据库调用是否消失。

答案 1 :(得分:1)

  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. 可以通过外部属性配置实体cahcing。见there。例如:

        <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>
    
  3. 结果,我们有纯JPA代码,外部配置用于缓存和其他提供商特定功能。这对Hibernate和EclipseLink来说非常有效。作为额外的奖励,我们为不同的应用程序模块提供了不同的缓存策略(例如,管理员Web应用程序不会缓存元数据表,但操作员Web应用程序缓存它只读)。

答案 2 :(得分:1)

这看起来对我有用,使用Hibernate ORM / EhCache 4.2.6.Final和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>

我用@javax.persistence.Cacheable注释了我的Entity类,我只看到Hibernate在获取不在缓存中的内容时记录SQL查询。关键似乎是使用JPA属性来指定是否启用缓存而不是特定于hibernate的属性。