问题描述
用户在使用了ACP做admin数据导入之后,在Web Client上创建某个subclass级别的Change,出现“Unable to save your changes. You have one error.”错误。
检查Server log,没有任何异常。只能通过Java Client的Java控制台输出必要的error,发现如下错误。
java.lang.NullPointerException
at com.agile.pc.cmserver.base.BaseFlexTableDAO.getFlexTableDataForCreate(BaseFlexTableDAO.java:62)
at com.agile.pc.cmserver.base.BaseObjectDAO.createObject(BaseObjectDAO.java:293)
at com.agile.pc.cmserver.base.BaseService.saveNewObject(BaseService.java:584)
at com.agile.pc.cmserver.base.BaseService.saveNewObject(BaseService.java:572)
at com.agile.pc.cmserver.base.BaseService.createObjectByNumber(BaseService.java:1247)
at com.agile.pc.cmserver.base.BaseService.createObjectByNumber(BaseService.java:1126)
at com.agile.pc.cmserver.base.CMSessionBean.processCreateObject(CMSessionBean.java:8534)
at com.agile.pc.cmserver.base.CMSessionBean.createObjectByNumberWithRqFields(CMSessionBean.java:253)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
分析
从上述的错误中,根据“Flex”的关键字,我们可以看出Change在创建过程中,使用到了某个自定义的attribute,但这个attribute又不在初始化启动持久的cache中。
自定义的attribute只存在于两种地方,Page Two和Page Three,其他地方不可能出现。因此,查看该Change 的class级别的Page Two和当前Subclass级别的Page Three,发现有一处地方使用到了自定义的attribute,名称为“Notify (By Group)”,id为2484527。当attribute为自定义时,JavaCLient中显示的Base ID就是其本身的ID。如下图:
试图打开这个attribute时,JavaClient显示空白页面且出现错误在控制台中。
Node (2484197 , 2484527) does not exist in the cache.
com.agile.admin.client.value.AdminException: Node (2484197 , 2484527) does not exist in the cache.
at com.agile.admin.server.ADictionary.getNodeByObjID(ADictionary.java:343)
at com.agile.admin.server.AdminSessionBean.getNode(AdminSessionBean.java:393)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
查询数据库后发现:
SQL >select id, parentid, description, objtype, inherit from nodetable where id = 2484527;
2484527 2484198 Notify (By Person) 1 1566
此处的数据显示为Notify (By Person)和JavaClient完全不匹配,而且inherit为1566,基类是MultiList03,并非是一个自定义的。如果是自定义,此处必须为0。怀疑另有一个attribute。继续深入查找,发现问题所在。
SQL> select id, parentid, description, objtype, inherit from nodetable where parentid= 2484198 and objtype=1 and inherit=1566;
2484533 2484198 Notify (By Group) 1 1566
2484527 2484198 Notify (By Person) 1 1566
在同一个tab中,不可能有2个或2个以上基于同一基类attribute的attribute。此处必有一个为错误的。
解决方法
- 方法一,由于1566被两个attribute继承,可以删除其中一个,具体方法是操作nodetable和propertytable。 带来的后果是,虽然系统能够保证Change能创建成功,但如果其中一个被其他对象引用到,会带入更多的新的错误。比如Advanced Search和Report,Criteria以及Privilege的Applied To都会有可能用到该attribute。
- 方法二,本着宁愿数据冗余的原则,将其中一个attribute的inherit置为0,使其成为一个customized attribute。客户如果发现有问题,可以通过JavaClient来正常合法的修改。 通过第二种方案,可以成功地创建Change,并且JavaClient也能正常地打开“Notify (By Group)”和“Notify (By Person)”。
是为解。