CXF发布web service时,hibernate关系循环的问题

两个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中写是不好使的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值