设置hibernate二级缓存
我是 hibernate 和 spring 的新手,我尝试使用 hibernate 二级缓存。但似乎不起作用。我有一个以下测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
@TransactionConfiguration
@Transactional
public class CacheTest extends AbstractTransactionalJUnit4SpringContextTests
{
@Test
public void testCache1()
{
System.out.println("Running testCache1");
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
MutableDAO<AppUser> appUserDAO = new MutableDAOImpl<AppUser>(AppUser.class, (SessionFactory) ctx.getBean("OnMediaSessionFactory"), 10);
assertNotNull("AppUser DAO is null.", appUserDAO);
SessionFactory sessionFactory = (SessionFactory)ctx.getBean("OnMediaSessionFactory");
long numberOfUsers = appUserDAO.countAll();
System.out.println("Number of rows :" + numberOfUsers);
final String cacheRegion = AppUser.class.getCanonicalName();
SecondLevelCacheStatistics settingsStatistics = sessionFactory.getStatistics().
getSecondLevelCacheStatistics(cacheRegion);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
appUserDAO.findAll();
stopWatch.stop();
System.out.println("Query time : " + stopWatch.getTotalTimeSeconds());
System.out.println(settingsStatistics);
}
@Test
public void testCache2()
{
System.out.println("Running testCache2");
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
MutableDAO<AppUser> appUserDAO = new MutableDAOImpl<AppUser>(AppUser.class, (SessionFactory) ctx.getBean("OnMediaSessionFactory"), 10);
assertNotNull("AppUser DAO is null.", appUserDAO);
SessionFactory sessionFactory = (SessionFactory)ctx.getBean("OnMediaSessionFactory");
long numberOfUsers = appUserDAO.countAll();
System.out.println("Number of rows :" + numberOfUsers);
final String cacheRegion = AppUser.class.getCanonicalName();
SecondLevelCacheStatistics settingsStatistics = sessionFactory.getStatistics().
getSecondLevelCacheStatistics(cacheRegion);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
appUserDAO.findAll();
stopWatch.stop();
System.out.println("Query time : " + stopWatch.getTotalTimeSeconds());
System.out.println(settingsStatistics);
}
}
我有
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
但我得到这样的输出:
Running testCache1
Number of rows :81
Query time : 0.129
SecondLevelCacheStatistics[hitCount=0,missCount=0,putCount=81,elementCountInMemory=81,elementCountOnDisk=0,sizeInMemory=219634]
Running testCache2
Number of rows :81
Query time : 0.063
SecondLevelCacheStatistics[hitCount=0,missCount=0,putCount=81,elementCountInMemory=81,elementCountOnDisk=0,sizeInMemory=219634]
我必须做什么才能让它工作?
I am new in hibernate and spring and I experiment with hibernate second level cache. But it seems doesn't work. I have a following test class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
@TransactionConfiguration
@Transactional
public class CacheTest extends AbstractTransactionalJUnit4SpringContextTests
{
@Test
public void testCache1()
{
System.out.println("Running testCache1");
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
MutableDAO<AppUser> appUserDAO = new MutableDAOImpl<AppUser>(AppUser.class, (SessionFactory) ctx.getBean("OnMediaSessionFactory"), 10);
assertNotNull("AppUser DAO is null.", appUserDAO);
SessionFactory sessionFactory = (SessionFactory)ctx.getBean("OnMediaSessionFactory");
long numberOfUsers = appUserDAO.countAll();
System.out.println("Number of rows :" + numberOfUsers);
final String cacheRegion = AppUser.class.getCanonicalName();
SecondLevelCacheStatistics settingsStatistics = sessionFactory.getStatistics().
getSecondLevelCacheStatistics(cacheRegion);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
appUserDAO.findAll();
stopWatch.stop();
System.out.println("Query time : " + stopWatch.getTotalTimeSeconds());
System.out.println(settingsStatistics);
}
@Test
public void testCache2()
{
System.out.println("Running testCache2");
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
MutableDAO<AppUser> appUserDAO = new MutableDAOImpl<AppUser>(AppUser.class, (SessionFactory) ctx.getBean("OnMediaSessionFactory"), 10);
assertNotNull("AppUser DAO is null.", appUserDAO);
SessionFactory sessionFactory = (SessionFactory)ctx.getBean("OnMediaSessionFactory");
long numberOfUsers = appUserDAO.countAll();
System.out.println("Number of rows :" + numberOfUsers);
final String cacheRegion = AppUser.class.getCanonicalName();
SecondLevelCacheStatistics settingsStatistics = sessionFactory.getStatistics().
getSecondLevelCacheStatistics(cacheRegion);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
appUserDAO.findAll();
stopWatch.stop();
System.out.println("Query time : " + stopWatch.getTotalTimeSeconds());
System.out.println(settingsStatistics);
}
}
and i have
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
but i get output like this:
Running testCache1
Number of rows :81
Query time : 0.129
SecondLevelCacheStatistics[hitCount=0,missCount=0,putCount=81,elementCountInMemory=81,elementCountOnDisk=0,sizeInMemory=219634]
Running testCache2
Number of rows :81
Query time : 0.063
SecondLevelCacheStatistics[hitCount=0,missCount=0,putCount=81,elementCountInMemory=81,elementCountOnDisk=0,sizeInMemory=219634]
what i have to do to get it work ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的测试看起来很奇怪,您为每个测试创建一个新的应用程序上下文,因此 Hibernate SessionFactory 及其二级缓存在测试之间无法生存。
正确的测试应该是这样的:
Your test looks very strange, you create a new application context for each test, therefore Hibernate
SessionFactory
doesn't survive between tests, as well as its second-level cache.Correct test would look like this:
首先,请记住 Hibernate 默认情况下不使用任何缓存提供程序。因此,您需要一个用于 Hibernate 2L 缓存的“外部”缓存提供程序。对于我的回答,我将使用 ehcache 和 Hibernate 3.3。请注意,最新版本的 Hibernate 中的配置已更改,因此请阅读文档以了解您正在使用的确切版本。
在您的 Hibernate 配置中,您错过了一个部分,即将 Hibernate 指向实际的提供者。 Hibernate.cache.provider_class 属性在 Hibernate 3.3 中执行此操作。将其值设置为
net.sf.ehcache.hibernate.SingletonEhCacheProvider
现在,您还需要一个 ehcache.xml,如下所示:
您没有显示您的 DAO,所以,我不确定它是否正确。请注意,您始终需要明确有关缓存的信息,因为它是针对特定位置的解决方案,而不是针对所有内容的通用解决方案。这意味着,在您的 DAO 中,您将添加一个查询提示,表明您的查询是可缓存的(从您的测试来看,您似乎需要查询缓存,而不仅仅是实体缓存)。
如果仍然无法使其工作,请参阅下面JIRA中的附件。它包含一个启用了缓存的 Maven 项目,因此,您可以将其与您的代码进行比较:
https ://issues.jboss.org/browse/JBPAPP-4224
First of all, remember that Hibernate doesn't uses any cache provider by default. So, you'll need an "external" cache provider for Hibernate's 2L cache. For my answer, I'll use ehcache and Hibernate 3.3. Note that the configuration was changed in more recent versions of Hibernate so, read the docs for the exact version you are using.
In your Hibernate configuration, you missed one part, which is to point Hibernate to the actual provider. The property
hibernate.cache.provider_class
does that for Hibernate 3.3. Set it's value tonet.sf.ehcache.hibernate.SingletonEhCacheProvider
Now, you'll need also an ehcache.xml, like this:
You didn't show your DAO, so, I'm not sure it's correct or not. Note that you always need to be explicit about cache, as it's meant to be used a solution for specific places, instead of generic solution for everything. That means, in your DAO, you'd add a query hint, stating that your query is cacheable (from your test, it seems you want query cache, not just entity caching).
If you are still unable to make it work, please see the attachment in the following JIRA. It contains a maven project with cache enabled, so, you may be able to compare it with your code:
https://issues.jboss.org/browse/JBPAPP-4224