第36周 | 2020年08月31日 - 2020年09月06日 |
---|---|
作者 | tanpenggood |
编辑 | tanpenggood |
#1634 dictText名称解析报错
https://github.com/zhangdaiscott/jeecg-boot/issues/1634
BUG是否复现
BUG复现
,确认BUG。
2020-09-02 10:47:04.448 [http-nio-8080-exec-6] INFO o.j.modules.system.controller.SysUserController:124 - com.baomidou.mybatisplus.extension.plugins.pagination.Page@2082b25d
2020-09-02 10:47:04.457 [http-nio-8080-exec-6] ERROR o.jeecg.common.exception.JeecgBootExceptionHandler:57 - java.util.ArrayList cannot be cast to java.lang.String
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
at org.jeecg.modules.system.service.impl.SysDictServiceImpl$$EnhancerBySpringCGLIB$$6de2300f.queryTableDictTextByKey(<generated>)
at org.jeecg.modules.system.aspect.DictAspect.translateDictValue(DictAspect.java:149)
at org.jeecg.modules.system.aspect.DictAspect.parseDictText(DictAspect.java:107)
at org.jeecg.modules.system.aspect.DictAspect.doAround(DictAspect.java:54)
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:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
原因分析
org.jeecg.modules.system.service.impl.SysDictServiceImpl#queryTableDictTextByKey
与org.jeecg.modules.system.service.impl.SysDictServiceImpl#queryTableDictByKeys
均使用了@Cacheable
注解缓存,且未自定义keyGenerator
,均使用默认 key 生成策略。
即它们的 redis key 分别为:
sys:cache:dictTable::SimpleKey [table,text,code,key]
对应的 redis value 为字符串类型。sys:cache:dictTable::SimpleKey [table,text,code,keys]
对应的 redis value 为 ArrayList 类型。
对比两个 redis key 的生成规则,细心的我们能发现它们在某种情况下
会存在 key 冲突。
即,生成的两个 redis key 一致,导致后使用该 redis key 读取数据的接口,会出现数据类型转换的异常。
某种情况下
是指,同时满足下面的所有条件:
- table == table
- text == text
- code == code
- key == keys
(上图为:sys:cache:dictTable::SimpleKey [table,text,code,key]
对应的 redis value 为字符串类型。)
(上图为:sys:cache:dictTable::SimpleKey [table,text,code,keys]
对应的 redis value 为 ArrayList 类型。)
解决方案
org.jeecg.common.constant.CacheConstant
增加SYS_DICT_TABLE_BY_KEY_CACHE
和 SYS_DICT_TABLE_BY_KEYS_CACHE
String SYS_DICT_TABLE_BY_KEY_CACHE = SYS_DICT_TABLE_CACHE + "ByKey";
String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys";
queryTableDictTextByKey
使用SYS_DICT_TABLE_BY_KEY_CACHE
作为 cacheNames
queryTableDictByKeys
使用SYS_DICT_TABLE_BY_KEYS_CACHE
作为 cacheNames
@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEY_CACHE)
public String queryTableDictTextByKey(String table,String text,String code, String key) {}
@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE)
public List<String> queryTableDictByKeys(String table, String text, String code, String keys) {}
注意
需要保证调整这里的 redis key 不会影响到其它业务。
修复后效果:
#1522 数据字典项 Redis 缓存
https://github.com/zhangdaiscott/jeecg-boot/issues/1522
与 #1634
为同一BUG,已在#1634
修复。
#1577 聚合路由 maximum call stack size exceeded
https://github.com/zhangdaiscott/jeecg-boot/issues/1577
https://gitee.com/jeecg/jeecg-boot/issues/I1R3NU