第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#queryTableDictTextByKeyorg.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

【JeecgBoot】bugfix No.36(2020年)_java


(上图为:sys:cache:dictTable::SimpleKey [table,text,code,key] 对应的 redis value 为字符串类型。)

【JeecgBoot】bugfix No.36(2020年)_redis_02


(上图为:sys:cache:dictTable::SimpleKey [table,text,code,keys] 对应的 redis value 为 ArrayList 类型。)

解决方案

org.jeecg.common.constant.CacheConstant增加SYS_DICT_TABLE_BY_KEY_CACHESYS_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 不会影响到其它业务。

修复后效果:

【JeecgBoot】bugfix No.36(2020年)_redis_03

#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")

【JeecgBoot】bugfix No.36(2020年)_SYS_04

下图为个人设置path指向子路由基础设置pathbug被修复。

【JeecgBoot】bugfix No.36(2020年)_java_05

聚合路由的个人设置菜单,能正常访问啦!

【JeecgBoot】bugfix No.36(2020年)_SYS_06

解决方案

调整个人设置菜单路径,使用聚合路由下的第一个子路由。

系统管理 -> 菜单管理 -> 个人页 -> 个人设置 -> 菜单路径调整为/account/settings/BaseSetting

【JeecgBoot】bugfix No.36(2020年)_redis_07