Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 设置休眠二级缓存_Hibernate_Spring_Second Level Cache - Fatal编程技术网

Hibernate 设置休眠二级缓存

Hibernate 设置休眠二级缓存,hibernate,spring,second-level-cache,Hibernate,Spring,Second Level Cache,我对hibernate和spring是新手,我尝试使用hibernate二级缓存。但它似乎不起作用。我有以下的测试课程: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext.xml" }) @TransactionConfiguration @Transactional public class CacheTest extends Abs

我对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);
     }
}

要让它工作,我必须做些什么?

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

正确的测试如下所示:

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]
@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);
     }      
 }
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>

    <diskStore path="./cache" />

    <defaultCache   maxElementsInMemory="10000" 
                    eternal="true"
                    overflowToDisk="true"
                    diskPersistent="true" 
                    diskExpiryThreadIntervalSeconds="120"
                    memoryStoreEvictionPolicy="FIFO" />

    <cache  name="com.mycompany.jpa.MyEntity" 
            maxElementsInMemory="50" 
            overflowToDisk="true" />

    <cache  name="org.hibernate.cache.StandardQueryCache" 
            maxElementsInMemory="50" 
            overflowToDisk="true" />

    <cache  name="org.hibernate.cache.UpdateTimestampsCache" 
            maxElementsInMemory="5000"
            overflowToDisk="true" />

</ehcache>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“classpath:applicationContext.xml”})
公共类CacheTest扩展了AbstractTransactionalJUnit4SpringContextTests
{   
@自动连线
私有可变dao-appUserDAO;
@自动连线
私人会话工厂会话工厂;
私人交易模板;
@自动连线
公共作废setPtm(平台交易管理ptm){
tx=新交易模板(ptm);
}
@试验
公共void doTestCache(){
//使用编程事务管理,因为我们需要2个事务
//用同样的方法
//第一次尝试
tx.execute(新建TransactionCallbackWithoutResult(){
public void doInTransactionWithoutResult(交易状态){
testCache();
}
});
//第二次尝试
tx.execute(新建TransactionCallbackWithoutResult(){
public void doInTransactionWithoutResult(交易状态){
testCache();
}
});
}
公共void testCache(){
long numberOfUsers=appUserDAO.countAll();
System.out.println(“行数:”+numberOfUsers);
最终字符串cacheRegion=AppUser.class.getCanonicalName();
SecondLevelCacheStatistics settingsStatistics=sessionFactory.getStatistics()。
getSecondLevelCacheStatistics(cacheRegion);
秒表秒表=新秒表();
秒表。开始();
appUserDAO.findAll();
秒表;
System.out.println(“查询时间:+stopWatch.getTotalTimeSeconds());
系统输出打印LN(设置统计);
}      
}

首先,请记住Hibernate默认情况下不使用任何缓存提供程序。因此,对于Hibernate的2L缓存,您需要一个“外部”缓存提供程序。对于我的答案,我将使用ehcache和hibernate3.3。请注意,配置在更新版本的Hibernate中已更改,因此,请阅读文档以了解您正在使用的确切版本

在Hibernate配置中,您遗漏了一个部分,即将Hibernate指向实际的提供者。属性
hibernate.cache.provider\u类为hibernate 3.3执行此操作。将其值设置为
net.sf.ehcache.hibernate.SingletonEhCacheProvider

现在,您还需要一个ehcache.xml,如下所示:

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]
@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);
     }      
 }
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>

    <diskStore path="./cache" />

    <defaultCache   maxElementsInMemory="10000" 
                    eternal="true"
                    overflowToDisk="true"
                    diskPersistent="true" 
                    diskExpiryThreadIntervalSeconds="120"
                    memoryStoreEvictionPolicy="FIFO" />

    <cache  name="com.mycompany.jpa.MyEntity" 
            maxElementsInMemory="50" 
            overflowToDisk="true" />

    <cache  name="org.hibernate.cache.StandardQueryCache" 
            maxElementsInMemory="50" 
            overflowToDisk="true" />

    <cache  name="org.hibernate.cache.UpdateTimestampsCache" 
            maxElementsInMemory="5000"
            overflowToDisk="true" />

</ehcache>

你没有展示你的刀,所以,我不确定它是否正确。请注意,您始终需要明确说明缓存,因为它是用于特定位置的解决方案,而不是用于所有内容的通用解决方案。这意味着,在DAO中,您将添加一个查询提示,说明您的查询是可缓存的(从测试来看,您似乎需要查询缓存,而不仅仅是实体缓存)

如果您仍然无法使其工作,请参阅以下JIRA中的附件。它包含一个启用缓存的maven项目,因此,您可以将其与代码进行比较:


实体类本身必须显式可缓存-您这样做了吗?是的,我有@Cache(usage=cacheconcurrentystrategy.READ\u WRITE)谢谢您的回答。但是什么是@Autowired public void setPtm(PlatformTransactionManagement ptm){tx=new TransactionTemplate(ptm);}以及在特定的PlatformTransactionManagement中?@Daniel:编程事务管理需要它,请参阅。由于您希望检查缓存值在事务之间是否存在,因此需要在测试方法内执行多个事务,编程事务管理是一种很好的安排方式。我执行了您的代码,但现在我得到了行数:81查询时间:0.142 SecondLevelCacheStatistics[hitCount=0,missCount=0,putCount=0,elementCountInMemory=0,elementCountOnDisk=0,sizeInMemory=0]行数:81查询时间:0.031秒级缓存统计[hitCount=0,missCount=0,putCount=0,elementCountInMemory=0,elementCountOnDisk=0,sizeInMemory=0]@丹尼尔:如果缓存配置正确,加载单个实体时应该可以正常工作。但是,
findAll()
似乎正在执行一个查询,所以您需要为该查询启用查询缓存的使用,@axtavt I将findAll()改为AppUser aUser=(AppUser)sessionFactory.getCurrentSession().load(AppUser.class,13351L)现在我得到:行数:81查询时间:0.0 SecondLevelCacheStatistics[hitCount=0,missCount=2,putCount=4,elementCountInMemory=4,elementCountOnDisk=0,sizeInMemory=10816]行数:81查询时间:0.0 SecondLevelCacheStatistics[hitCount=0,missCount=2,putCount=4,elementCountInMemory=4,elementCountOnDisk=0,sizeInMemory=10816]但我还是得到了命中率=0