【问题标题】:JPA native query second level cacheJPA原生查询二级缓存
【发布时间】:2014-05-28 13:58:29
【问题描述】:

我需要使用 JPA 对本机 sql 使用二级缓存。 我没有找到方法来做到这一点。如果 JPA 支持本机查询缓存,有人可以建议方式

【问题讨论】:

  • 我已经发布了一些 ehcache 缓存提供程序的示例配置,我写了一篇关于二级缓存陷阱的博文,可能也会有所帮助,看看blog.jhades.org/…

标签: jpa


【解决方案1】:

JPA 支持使用@Cacheable 注释的二级缓存,请参阅here 官方文档。二级缓存的配置是特定于持久化提供者的,这是一个如何设置休眠的示例。

首先添加与缓存提供程序的集成,在本例中为 ehcache:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>SOME-HIBERNATE-VERSION</version>
</dependency>

然后将这个添加到会话工厂配置中:

<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">/your-cache-config.xml</prop>

然后添加一个ehcache xml配置文件:

<?xml version="1.0" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             updateCheck="false"
       xsi:noNamespaceSchemaLocation="ehcache.xsd" name="yourCacheManager">

     <diskStore path="java.io.tmpdir"/>

     <cache name="yourEntityCache"
            maxEntriesLocalHeap="10000"
            eternal="false"
            overflowToDisk="false"
            timeToLiveSeconds="86400" />

     <cache name="org.hibernate.cache.internal.StandardQueryCache"
            maxElementsInMemory="10000"
            eternal="false
            timeToLiveSeconds="86400"
            overflowToDisk="false"
            memoryStoreEvictionPolicy="LRU" />

  <defaultCache
          maxElementsInMemory="10000"
          eternal="false"
          timeToLiveSeconds="86400"
          overflowToDisk="false"
          memoryStoreEvictionPolicy="LRU" />
</ehcache>

缓存应该可以工作了,尝试用@Cache(本地Hibernate注解)或标准@CacheableJPA注解来注解一个实体。查询需要单独标记为缓存。

这是缓存命名查询的方法:

@NamedQuery(name="account.queryName",
   query="select acct from Account ...",
   hints={
       @QueryHint(name="org.hibernate.cacheable",
       value="true")
   }     
})

这是缓存条件查询的方法:

List cats = session.createCriteria(Cat.class)
    .setCacheable(true)
    .list();

【讨论】:

  • 感谢您的回复。我没有实体,也不想创建。我们已经完成了原生查询,所以现在我们要为此添加二级缓存。
【解决方案2】:

JPA L2 缓存是为实体设计的。如果你没有,那么首先,使用 JPA 是没有意义的,其次,即使你有实体,本机查询也不一定会返回它们,所以没有什么是可缓存的。

显然,您可能会找到一种实现,该实现将允许在 L2 缓存中缓存来自本机 (SQL) 查询的大量信息,但是您没有使用 JPA 规范标准,而是使用供应商规范(这将停止工作如果您曾经更改过 JPA 提供程序)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-28
    • 2011-12-18
    • 2011-08-31
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多