第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
BUG是否复现
BUG复现
,确认BUG。
[Vue warn]: Error in render: "RangeError: Maximum call stack size exceeded"
found in
---> <RouterLink>
<MenuItem>
<ConnectMenuItem>
<ProxyConnectMenuItem>
<Anonymous>
<Trigger>
<Anonymous>
<ATooltip>
<AMenuItem>
<DOMWrap>
<SubPopupMenu>
<ConnectSubPopupMenu>
<ProxyConnectSubPopupMenu>
<SubMenu>
<ConnectSubMenu>
<ProxyConnectSubMenu>
<ASubMenu>
<DOMWrap>
<SubPopupMenu>
<ConnectSubPopupMenu>
<ProxyConnectSubPopupMenu>
<StoreProvider>
<Menu>
<AMenu>
<SMenu>
<ALayoutSider>
<SideMenu> at src/components/menu/SideMenu.vue
<Anonymous>
<ALayout>
<GlobalLayout> at src/components/page/GlobalLayout.vue
<TabLayout> at src/components/layouts/TabLayout.vue
<ALocaleProvider>
<LocaleReceiver>
<AConfigProvider>
<App> at src/App.vue
<Root>
原因分析
经过多个版本的回溯比较,最终定位为数据问题
。
使用聚合路由时,父菜单的菜单路径
需指向它的子路由。
下图为个人设置
的path
未指向任何一个子路由,
导致[Vue warn]: Error in render: "RangeError: Maximum call stack size exceeded"
)
下图为个人设置
的path
指向子路由基础设置
的path
,bug
被修复。
为聚合路由
的个人设置菜单,能正常访问啦!
解决方案
调整个人设置
的菜单路径
,使用聚合路由下的第一个子路由。
系统管理 -> 菜单管理 -> 个人页 -> 个人设置 -> 菜单路径
调整为/account/settings/BaseSetting