两个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中写是不好使的。
在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中写是不好使的。