在J2SE中使用JPA2.0@Cacheable与Spring、EHCache和Hibernate,而不使用Hibernate特定的注释

在J2SE中使用JPA2.0@Cacheable与Spring、EHCache和Hibernate,而不使用Hibernate特定的注释,hibernate,spring,caching,jpa-2.0,ehcache,Hibernate,Spring,Caching,Jpa 2.0,Ehcache,我试图让JPA2.0缓存在使用Hibernate和EhCache的Spring3.0.5应用程序中工作。我不希望我的应用程序绑定到Hibernate和EhCache,我希望它尽可能只使用纯JPA代码 通过在实体类的顶部设置Hibernate特定的@Cache注释,并指定org.Hibernate.cacheable作为命名查询的查询提示,我成功地使缓存与EHCache和Hibernate一起工作 但是,当我尝试将它们切换到@Cacheable(true)并将查询提示javax.persisten

我试图让JPA2.0缓存在使用Hibernate和EhCache的Spring3.0.5应用程序中工作。我不希望我的应用程序绑定到Hibernate和EhCache,我希望它尽可能只使用纯JPA代码

通过在实体类的顶部设置Hibernate特定的
@Cache
注释,并指定
org.Hibernate.cacheable
作为命名查询的查询提示,我成功地使缓存与EHCache和Hibernate一起工作

但是,当我尝试将它们切换到
@Cacheable(true)
并将查询提示
javax.persistence.cache.retrieveMode
设置为
“CacheRetrieveMode.USE”
(我也尝试了
“USE”
)时,它不起作用,应该缓存的命名查询只是从数据库中再次检索。我正在使用
hints=…

我尝试了
启用选择性
禁用选择性
等多种组合,但似乎都没有效果

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


谢谢。

好吧,这不是纯粹的JPA,但我使用了Spring()的EhCache注释,它工作得很好。注释要用
@Cacheable(cacheName=“myCache”)
缓存的DAO方法,在Spring配置中配置缓存,并观察DB调用消失

  • 使用Hibernate JPA impl进行查询缓存在当前版本4.1之前,如果没有提示org.Hibernate.cacheable,就不可能进行查询缓存。当然,您可以将其存储在命名查询防御中的xml描述符中,并为不同的JPA提供程序更改它(或者存储所有变体的定义提示)。但在我们的项目中,我们实现了额外的实用程序,通过外部配置(props)向命名查询添加提示。例如:

    ru.citc.jpa.queryhint.[query\u name]=org.hibernate.cacheable\=true,javax.persistence.cache.retrieveMode\=USE,等等

  • 实体编码可以通过外部属性进行配置。看见例如:

        <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>
    
    读写,脚本执行
    读写、脚本执行
    只读,ScriptDesignCollections
    

  • 因此,我们有纯JPA代码,带有缓存的外部配置和其他特定于提供者的特性。这对冬眠和日食非常有效。作为额外的奖励,我们为不同的应用程序模块提供了不同的缓存策略(例如,管理员web app不缓存元数据表,但操作员web app将其缓存为只读)。

    这似乎对我有用,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>
    
    
    org.hibernate.cache.ehcache.EhCacheRegionFactory
    启用\u选择性
    

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

    您使用的是哪个版本的hibernate?由于这是在3.5中实现的,请参阅。它是否适用于Hibernate注释?仅仅是JPA的Anno被破坏了吗?如果不是,则可能是您设计查询的方式。您是否可以检查底层缓存(即EHCache)在支持“@Cacheable(true)”和“javax.persistence.cache.retrieveMode”方面是否存在任何问题?我怀疑可能有什么问题。当数据库中的数据被修改时,@Cacheable'会工作吗?我的意思是缓存数据是如何失效的?您需要注释您想要用来刷新缓存的方法,通常是在更新和删除DAO方法上。看见有两个基本选项:清空缓存(更简单的方法),或原子删除缓存项(更复杂)。谢谢,但这不是我想要的。我正在寻找一个纯粹的JPA解决方案。对于特定于供应商的解决方案,我可以简单地使用EHCache和Hibernate特定于供应商的注释,这很好。