Hibernate二级缓存似乎无法正常工作

时间:2010-06-29 16:06:53

标签: java hibernate orm caching second-level-cache

我目前正在尝试使用hibernate附带的缓存提供程序来运行hibernate。

net.sf.ehcache.hibernate.SingletonEhCacheProvider

我在ecache.xml中启用了默认缓存和类特定缓存,我在hibernate.cfg.xml文件中引用了该缓存。定义类/映射文件特定高速缓存以处理多达20000个对象。

然而,由于我在其中一个映射文件上启用了缓存映射,因此我没有看到任何性能提升。我正在测试它。

我的测试如下。

加载我测试的特定映射文件的10000个对象(这应该击中DB并成为瓶颈)。 接下来我将加载相同的10000个对象,因为我希望缓存被击中并看到显着的性能提升。尝试在hibernate映射xml文件中同时使用“只读”和“读写”缓存映射进行测试。

我想知道他们需要做些什么才能确保在加载对象时数据库之前的缓存被命中?

注意作为测试im pagin的一部分通过这些10000记录使用类似于下面的内容(在时间分页1000条记录)。

Criteria crit = HibernateUtil.getSession() .createCriteria( persistentClass );
       crit.setFirstResult(startIndex);
       crit.setFetchSize(fetchSize);
       return crit.list();

已经看到标准有一个缓存模式设置器(setCacheMode())所以我应该做些什么?

我注意到在内存中使用了下面的统计代码,即10000个对象(好的hiberante脱水onjects,我想象??) 出于某种原因,我得到了0次点击,更令人担忧的是0次失败,所以看起来它看起来就像它在查看时根本没有进入缓存,即使统计代码似乎告诉我内存中有10000个对象。 / p>

关于我在做什么的任何想法?我认为我得失的事实很好,因为它意味着正在使用缓存,但我无法弄清楚为什么我没有得到任何缓存命中。是否使用setFirstResult()setFetchSize()并使用标准。

System.out.println("Cache Misses = " + stats.getSecondLevelCacheMissCount());
System.out.println("Cache Hits Count = " + stats.getSecondLevelCacheHitCount());

System.out.println("2nd level elements in mem "+ stats.getSecondLevelCacheStatistics("com.SomeTestEntity").getElementCountInMemory());

1 个答案:

答案 0 :(得分:13)

二级缓存适用于“按主键查找”。对于其他查询,您需要缓存查询(如果启用了查询缓存),在您的情况下使用Criteria#setCacheable(boolean)

Criteria crit = HibernateUtil.getSession().createCriteria( persistentClass );
crit.setFirstResult(startIndex);
crit.setFetchSize(fetchSize);
crit.setCachable(true); // Enable caching of this query result
return crit.list();

我建议阅读:


  

如果我缓存查询,那么它们都是查询中的hibernate实体,然后在二级缓存中可用吗?

是的,他们会的。这在我提到的链接中用黑色解释为:“请注意,查询缓存不会缓存结果集中实际实体的状态;它只缓存标识符值和值类型的结果。所以查询缓存应始终与二级缓存“一起使用。你看过了吗?

  

由于我的印象是使用查询缓存与使用hibernate二级缓存完全不同。

它是不同的(用于缓存entrie的“密钥”是不同的)。但查询缓存依赖于L2缓存。

  

从您的回答中,您似乎建议查询缓存和二级缓存都相同,并且要生成缓存命中,我需要使用“按主键查找”。

我只是说你需要缓存查询,因为你不是“通过主键查找”。我不清楚什么不清楚。您是否尝试在查询或条件对象上调用setCacheable(true)?很抱歉坚持但是,您是否阅读了我发布的链接?