@Cacheable java.lang.NullPointerException: null at java.lang.String.concat(String.java:2027)
异常信息
java.lang.NullPointerException: null
at java.lang.String.concat(String.java:2027)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:117)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:130)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:50)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:348)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:121)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:262)
at org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.key(CacheOperationExpressionEvaluator.java:117)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:741)
at org.springframework.cache.interceptor.CacheAspectSupport.generateKey(CacheAspectSupport.java:557)
at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:501)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:388)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:326)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.jfintech.jbs.biz.ProductBiz$$EnhancerBySpringCGLIB$$27398e56.findProductInfoWhiteList(<generated>)
at com.jfintech.jbs.service.impl.ProductServiceImpl.getProductList(ProductServiceImpl.java:97)
at com.jfintech.jbs.controller.ProductController.lambda$queryProductList$49(ProductController.java:58)
at org.springframework.web.context.request.async.WebAsyncManager$5.run(WebAsyncManager.java:327)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
错误代码示例:
@Cacheable(cacheNames = "productInfos",cacheManager="jfinetchRedisCacheManager", key = "'jbs:product:white:'.concat(#reqest.getChannelCode()).concat(#p2)")
public List<ProductInfoVO> findProductInfoWhiteList(CommonRequest<ReqProductVO> reqest,String productCodes){
List<ProductInfoVO> redisList = productService.findList(reqest);
redisList = redisList.stream().filter(it ->
ProductStatusEnum.OPEN.getCode().equals(it.getStatus()) || (it.getStatus().equals(ProductStatusEnum.WHITE.getCode()) && productCodes.indexOf(it.getProductId().concat("]"))>=0)
).collect(Collectors.toList());
return redisList;
}
错误原因分析
- 出现此问题应该是入参为空导致
于是debug,发现reqest.getChannelCode()和productCodes都不为空,继续分析异常信息。
看到这源码基本上能肯定是String concat的时候为空,这样看来应该是注解中的参数获取不正确。 - 参数获取方式不正确
继续回去检查代码发现第二参数写的#p2
@ Cacheable(key = “‘key’+#p0 +#p1 +#p2” )一般用法,#p0表示方法的第一个参数,#p1表示第二个参数,以此类推。
解决方法
把#p2改成#p1,问题解决,正确代码如下。
@Cacheable(cacheNames = "productInfos",cacheManager="jfinetchRedisCacheManager", key = "'jbs:product:white:'.concat(#reqest.getChannelCode()).concat(#p1)")
public List<ProductInfoVO> findProductInfoWhiteList(CommonRequest<ReqProductVO> reqest,String productCodes){
List<ProductInfoVO> redisList = productService.findList(reqest);
redisList = redisList.stream().filter(it ->
ProductStatusEnum.OPEN.getCode().equals(it.getStatus()) || (it.getStatus().equals(ProductStatusEnum.WHITE.getCode()) && productCodes.indexOf(it.getProductId().concat("]"))>=0)
).collect(Collectors.toList());
return redisList;
}