记一次解决Null key returned for cache operation的过程

起因

在某个入参为map的方法上加了@Cacheable注解后,测试传入空json(在mapper业务逻辑里面传入空json是搜全表)时,报错:Null key returned for cache operation
网上查了各种解决方案,挺多都是说SPEL解析式解析key值出问题啥的,有点像是底层问题,而框架底层代码我一个小白是不敢动的,就非常抓狂。网上找到的的解决方法:

  • 改@Cacheable注解的入参为p1p2之类的
  • 给编译加-parameters参数的(不推荐)
  • 炫技类自己写key generator
    不过最后结合我自己的情况,加上同事的指导,以上的解决方案我都不需要
    我只需要在controller加一个数据预处理就好了。
    把我的解决过程发出来记录分享下~希望能帮助到跟我一样抓狂的小白

代码结构描述

Map<String, String> {//仅描述"XXX" : "xxx"
}
//Controller
public class XXXColtroller {public ControllerRetType getXXX (@RequestBody Map<String, String> map) {......ServiceRetType serviceRetVal = XXXService.getXXX(map);......}
}
//Service
public class XXXService {@Cacheable(value = "XXXCache", key = "#map[XXX]")//重要public ServiceRetType getXXX (Map<String, String> map) {......MapperRetType mapperRetVal = XXXMapper.getXXX(map);......}
}


<select id="getXXX" resultType = "java.util.HashMap"
parameterType = "java.util.HashMap">select * from XXTable a where 1 = 1<if  test="XXX != '' and XXX != null">AND a.XXX = #{XXX}if>
select>

Bug产生过程:Postman构造json测试

  • 当json含有 {“XXX” : “xxx”}时,可以顺利查出来,也能成功缓存,因为这个时候缓存的key (就是#map[XXX])是存在的。
  • 当json不含有"XXX"这个key时,如json={},本来要的效果是查全表,结果直接报错:Null key returned for cache operation

Bug原因分析

就如代码提供的错误信息:Null Key,service的入参map中根本没有"XXX"这个key,那自然就是null key。

如何解决?

方法1:绕开key为null的情况

仅需给上文的@Cacheable注解添加一个参数:

@Cacheable(value = "XXXCache", key = "#map[XXX]", condition = "#map[XXX] != null")

效果:当请求的map参数没有"XXX"这个key的时候(#map[XXX] = null),不走缓存,直接走数据库查询
不满足condition条件的情况,@Cacheable不会处理,那么就自然不会报错啦~

方法2:对空值做预处理

具体到本次情况,当入参map不含有"XXX"的key时,我们在Controller手动给它赋一个初值~
方法2相比方法1的好处在于,key为null时也可以缓存了,等于说所有状况都可以缓存。

public class XXXColtroller {public ControllerRetType getXXX (@RequestBody Map<String, String> map) {......map.putIfAbsent("XXX", "");//对空值做预处理ServiceRetType serviceRetVal = XXXService.getXXX(map);......}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部