两个bean,比如是1对多的关系 在hibernate的映射文件里,互相都映射的话, CXF在生成soap的XML时会报这样的错: org.apache.cxf.binding.soap.SoapFault: Marshalling Error: A cycle is detected in the object graph. This will cause infinitely deep XML
反正就是CXF发现是个圈,A找B,B找A,是个无限循环,所以报个错出来。
怎么解决呢?
有的说,这样: @XmlTransient public Set<User> getUserSet() { return userSet; } 在引起循环的get方法上加个@XmlTransient,那么生成XML时就会忽略这步了,所以就不会循环了。
试了下,好像有时候有null的什么问题,稀里糊涂~~~
后来,找到这个方法:
public abstract class User implements CycleRecoverable{
//... public Object onCycleDetected(Context arg0) { Company temp = new Company (); temp.setId(id); return temp; }
}
也就是在可能引起循环的bean上,实现CycleRecoverable接口, 然后加一个onCycleDetected方法,return一个临时对象。 反正是个圈,随便搞一个对象,结束这个圈就行了。 验证,好使,OK~~~ ================================================== 进一步实践发现,用onCycleDetected方法在数据较多时,仍然会引起循环。 比如多对多的关系时,A表数据1-->B表数据2-->A表数据3-->B表数据4, 由于是多对多的关系,乱成了一张网,却还没有循环,导致onCycleDetected方法得不到执行。
所以,仅仅用onCycleDetected方法还不够,还要配合@XmlTransient使用。
比如有ReportType类,它有getTypeItems()方法,也就是找所有的子记录。 @XmlTransient public Set<ReportTypeItem> getTypeItems() { return typeItems; }
用@XmlTransient的话,生成soap时,就会忽略getTypeItems()方法, 实际发送的数据中,就压根没有typeItems属性。 也就是取父的数据时,不取子数据,想取时,单独来个接口,取子的List就是了。 把所有的类似这种的父类中的get子List的方法都用@XmlTransient注掉就OK了,不会有循环引用的问题了。 ================================================== 而在子类中,引用所属父类的属性,不要使用@XmlTransient。 如ReportType类有个version属性,表示它所属的版本对象。 ReportType类和Version类的关系,ReportType类就是子类了。 @XmlTransient public Version getVersion() { return version; } 如果使用了@XmlTransient,取得数据时,就不会有version属性了。 同时,更重要的一点,没有version属性了, 添加ReportType时,由于version没有值,就无法添加了。 说的比较晕,实际弄一下就明白了。 总之,这种反向引用父类的不要加XmlTransient。 ==================================================== 进一步,由于ReportType类有version属性了,而Version本身是一个类, 所以返回的数据是类似这样一个结构: <id xsi:nil=""true""/> <typeName>11</typeName> <typeNo>11</typeNo> <version> <active>0</active> <id>c3b3cde3416d41d9a50406bfd8d40485</id> <versionNumber>2</versionNumber> </version> 恭喜你,可能会遇到这样的错误:
ReferenceError: Error #1065: Variable Version is not defined. at global/flash.utils::getDefinitionByName() 也就是变量Version没定义。
很晕,明明编译没错误,该有的都有,为什么报错呢~~~ 弄了一天,终于明白个大概。 简单的说,就是返回的xml数据,Flex要把它恢复成类的形式, 也就是动态构建对象了,而这里的Version动态创建的时候,没找到类定义, 所以报错了。
原因是Flex编译器,对于没有实际使用的类,没给编译到swf中? 即使是import了,也不好使~~~~反正很晕。
解决办法就是:
import package.User; private var _dummyUser:User; //声明一个变量 User; //或者更简单的,写个类名就行了。
还有重要的一点,要在application中声明,在模块module中写是不好使的。 ======================================================"
|