@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;
}