Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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 SpringEhcache只有在同一请求中调用该方法时才能工作_Hibernate_Spring Mvc_Spring Data_Ehcache - Fatal编程技术网

Hibernate SpringEhcache只有在同一请求中调用该方法时才能工作

Hibernate SpringEhcache只有在同一请求中调用该方法时才能工作,hibernate,spring-mvc,spring-data,ehcache,Hibernate,Spring Mvc,Spring Data,Ehcache,我试图缓存我的结果,但每次对页面的调用(刷新)都会命中数据库。谢谢你的帮助 控制器 showPage(){ MyPage<PhoneInfo> myPage = (MyPage<PhoneInfo>) phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(page.intValue(), size.intValue())); //further experiment..

我试图缓存我的结果,但每次对页面的调用(刷新)都会命中数据库。谢谢你的帮助

控制器

showPage(){
    MyPage<PhoneInfo> myPage = (MyPage<PhoneInfo>) phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(page.intValue(), size.intValue()));
    //further experiment.. below does not hit db
    myPage = (MyPage<PhoneInfo>) phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(page.intValue(), size.intValue()));
}
src/resources/ehcache.xml

<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:noNamespaceSchemaLocation="ehcache.xsd"     updateCheck="true"  monitoring="autodetect"     dynamicConfig="true">

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

    <cache name="myPageCache"       maxEntriesLocalHeap="1000"      maxEntriesLocalDisk="10000"         eternal="false"         diskSpoolBufferSizeMB="20"      timeToIdleSeconds="86400" timeToLiveSeconds="86400"         overflowToDisk="false"      memoryStoreEvictionPolicy="LFU"         transactionalMode="off">        <persistence strategy="localTempSwap" />    </cache>

</ehcache>

更新1 下面列出服务方法

Cacheable(value = "myPageCache", key = "{#options, #pageable}")
public MyPage<PhoneInfo>findAllByOption(PhoneOption options, MyPage<PhoneInfo> pageable){
    MyPage<PhoneInfo> myPage = phoneInfoRepoImpl.findAll(options, pageable);
    myPage.setTotalRows(_phoneInfoService.getCount(options, pageable));
    return myPage;
}

@Cacheable(value = "myPageCache", key = "#options")
public int getCount(PhoneOption options, MyPage<PhoneInfo> pageable){
    return phoneInfoRepoImpl.getCount(options, pageable);
}
Cacheable(value=“myPageCache”,key=“{#options,#pageable}”)
公共MyPagefindAllByOption(电话选项,MyPage可分页){
MyPage MyPage=phoneinforpoimpl.findAll(选项,可分页);
setTotalRows(_phoneInfoService.getCount(选项,可分页));
返回myPage;
}
@可缓存(value=“myPageCache”,key=“#选项”)
public int getCount(电话选项,MyPage可分页){
返回phoneInfoRepoImpl.getCount(选项,可分页);
}
更新2 单元测试

@Test
public void test1(){
    PhoneOption options = new PhoneOption();
    options.setName("239");
    options.setStatus('1');
    MyPage<PhoneInfo> myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //hits db, Ok
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //skips db, OK
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(2, 20)); //hits db, OK as MyPage changed
}

@Test
public void test2(){
    PhoneOption options = new PhoneOption();
    options.setName("239");
    options.setStatus('1');
    MyPage<PhoneInfo> myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //these options exactly same as Test1, skips db, OK!
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //skips db, Ok
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(2, 20)); //skips db, Ok
}
@测试
公共void test1(){
PhoneOption options=新的PhoneOption();
选项。设置名称(“239”);
期权。设定状态(“1”);
MyPage MyPage=phoneInfoService.findAllByOption(选项,new MyPage());//点击数据库,确定
myPage=phoneInfoService.findAllByOption(选项,new myPage());//跳过数据库,确定
myPage=phoneInfoService.findAllByOption(选项,新建myPage(2,20));//点击数据库,当myPage更改时确定
}
@试验
公共无效测试2(){
PhoneOption options=新的PhoneOption();
选项。设置名称(“239”);
期权。设定状态(“1”);
MyPage MyPage=phoneInfoService.findAllByOption(选项,new MyPage());//这些选项与Test1完全相同,跳过数据库,OK!
myPage=phoneInfoService.findAllByOption(选项,new myPage());//跳过数据库,确定
myPage=phoneInfoService.findAllByOption(选项,新建myPage(2,20));//跳过数据库,确定
}
更新3在所有测试对象中实现hashCode和equals

现在在单元测试中,它一直都会命中db!因此,行为恶化了。
hashcode对于equal/same对象是相同的,equals工作正常,对于具有类似属性的对象返回true。

您的键
“{#options,#pageable}”
每次都会有新值,即使您在这些对象中传递相同的值集,因为它们在每次页面刷新后都是全新的对象。因此,它们在每次第一次调用时都会被缓存。为了避免这种情况,您需要更改键。请尝试使用对象内的字段,如
#object.field

组成键的元素需要定义适当的
等于
hashcode
,这样即使您最终得到不同的实例,相等的值将导致正确的缓存命中。

假设您已将@Cacheable注释放置在findAllByOption方法上,则它是否从缓存中拾取取决于您传递的参数。如果每次页面刷新都是相同的,那么肯定是从缓存中获取的。此外,缓存的生存时间为86400ms。你的页面刷新调用的频率是多少?嗨@Rakesh,是的,我在方法上有缓存。刷新期间传递的参数完全相同,每次页面刷新都是相同的,而不是从缓存中获取。对于测试,我将在几秒钟内刷新页面。。我明白了,尽管您在options对象中可能有相同的值,但由于它始终是一个具有不同hashkey的新对象,所以它不会像您期望的那样工作。您需要有不同的密钥生成策略。您可以尝试类似#options.field1+#options.field2…My options是一个包含大量字段(如id、类型、列表等)的类,任何或所有字段都可以为空。在这种情况下,如何生成密钥?已尝试#options.id+#options.code,但两者都为null,引发错误类型为“null”和“null”的对象之间不支持运算符“ADD”混合options.hashCode()中的所有字段是否有意义?这样行吗?然后我可以使用#选项作为键入服务方法吗?理想情况下,如果是这种情况,您不应该缓存您的结果,因为可以有多个组合,但如果您有一组固定的必填字段,请使用它们来形成键。是的,选项实际上是一组搜索选项,因此结果可能会非常不同;该应用程序灵活而健壮,对许多用户来说速度很慢,认为缓存会非常有益。必填字段集必须是唯一的,因为它是键,对吗?我的场景有更好的替代方案吗?为什么我说不应该在场景中缓存,因为存在多个组合,对于每个组合,您的输出都将被缓存,并且缓存大小可能很容易达到它的限制。正如您所说的,它与搜索相关,Elasticsearch可能是最合适的。实现了equals&hascode,行为更糟糕,总是命中缓存。。在更新中,我学习了hashcode和equals,它帮助我朝着正确的方向前进,所以谢谢。
@Test
public void test1(){
    PhoneOption options = new PhoneOption();
    options.setName("239");
    options.setStatus('1');
    MyPage<PhoneInfo> myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //hits db, Ok
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //skips db, OK
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(2, 20)); //hits db, OK as MyPage changed
}

@Test
public void test2(){
    PhoneOption options = new PhoneOption();
    options.setName("239");
    options.setStatus('1');
    MyPage<PhoneInfo> myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //these options exactly same as Test1, skips db, OK!
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>()); //skips db, Ok
    myPage = phoneInfoService.findAllByOption(options, new MyPage<PhoneInfo>(2, 20)); //skips db, Ok
}