hibernate - 设置hibernate二级缓存

标签 hibernate spring second-level-cache

我是 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]

我必须做什么才能让它工作?

最佳答案

您的测试看起来很奇怪,您为每个测试创建一个新的应用程序上下文,因此 Hibernate SessionFactory 及其二级缓存在测试之间无法生存。

正确的测试如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class CacheTest extends AbstractTransactionalJUnit4SpringContextTests
{   
    @Autowired
    private MutableDAO<AppUser> appUserDAO;

    @Autowired
    private SessionFactory sessionFactory;

    private TransactionTemplate tx;

    @Autowired
    public void setPtm(PlatformTransactionManagement ptm) {
        tx = new TransactionTemplate(ptm);
    }

    @Test
    public void doTestCache() {
        // Using programmatic transaction management since we need 2 transactions
        // inside the same method

        // 1st attempt
        tx.execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(TransactionStatus status) {
                testCache();
            }
        });

        // 2nd attempt
        tx.execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(TransactionStatus status) {
                testCache();
            }
        });

    }

    public void testCache() {
        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);
     }      
 }

关于hibernate - 设置hibernate二级缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5181479/

相关文章:

java - SpringBoot - RequestMapping 获取路径作为变量?

java - 使用hibernate二级缓存进行实体更新

java - 确定二级缓存是否在 hibernate 中工作的问题

java - 使用 JPA 和 Hibernate (NotNull) 映射集合的最新子项

java - Spring JPA 多对多,额外列未更新

java - Struts + hibernate : large memory consumption arise during reading big data arrays

spring - 更新到最新版本后替换@EnableSwagger2

java - 当两个事务同时发生并相互影响时,根据另一个表的数据更新一行表的方法是什么

java - Maven javadoc :javadoc works but javadoc:aggregate throws errors that look like compiler errors

hibernate - 运行 JPQL 更新语句时 Hibernate 二级缓存是否失效