WebService调用一对多关联关系时出现 死循环:A cycle is detected in...
通过WebService调用一对多关联关系时引起的问题:A cycle is detected in the object graph
具体异常信息:
org.apache.cxf.interceptor.Fault: Marshalling Error: A cycle is detected in the object graph. This will cause infinitely deep XML: cn.jssms.platform.model.system.AppUser@75fce7 ->cn.jssms.platform.model.system.AppRole@195266b -> cn.jssms.platform.model.system.AppUser@75fce7
AppUser-->AppRole-->AppUser
在网上查阅资料后发现两个VO类中存在关联关系,可能是1:n 或n:1关系,应该跟Hibernate反射有关系。
循环引用:
Parent 和 Child是1:n的关系, Parent含有一个child的列表children,child对于parent有一个引用,那这两个对象之间就存在循环引用的关系.
我们不能 直接将带有环的对象暴露给webservice,因为这会导致最终生成xml的时候会陷入死循环最后栈溢出,所以cxf检测出对象存在cycle会抛出一 个异常阻止进一步发布webservice.(以前的XFire可没这么聪明,它没有检测机制,直接就去序列化xml结果会导致 OutOfMemory).
如何解决呢?就是要破掉这个环,去某一端,如何在不破坏原有设计的情况下做到这一点,就是要使用@XmlTransient
这个annotation会标明这个字段不要解析成xml,所有你不想解析进webservice的都可以通过这个标签来标记
注:cxf默认采用JAXB做databindings,如果要用aegis,相应的就要用@IgnoreProperty这个元注释
像这种情况,我们一般要打破子对父的引用,就是要打破Child对于Parent的引用.注意要在parent的get方法上面加而不是在parent的声明处.
这样从生成的wsdl里面我们就看不到child里有对于parent的引用
虽然client能够拿到children列表了,但通过child得不到parent的信息,因为在client现在是单向的,那我也想访问parent怎么办?
这里有一个解决办法,在Parent下面加入如下代码:
public void afterUnmarshal(Unmarshaller u, Object parent) {
this.parent = (Parent) parent;
}
怎么做到的?背后的道理是这样的:
循环的双向关系,一端到另一端的关系确定了以后,反过来另一端也就确定了.
cxf在解析wsdl映射成对象的过程中(也就是unmarshal),处理Parent并处理它所包含的child,结果发现parent引 用的child有afterUnmarshal方法,然后把自己的引用通过该方法传递给child,这样child也具有了对于 parent的引用,这一切都是在客户端完成的.真的是很聪明的做法.
这些功能必须要cxf来做客户端才能实现,但我们可以利用这种技术来在其他客户端实现这个功能.比如flex,.net, php 等等.
one more thing
上面的例子首先访问的是parent,cxf可以拿到两端的信息,但如果先访问child就拿不到parent了.
那么如果把@XmlTransient加到Parent, 同样道理, child可以得到parent的信息,但是这个parent的getChildren里恐怕就只有那一个child了.
所以还是看具体设计,如果parent需要经常访问child,第一种最好,如果child要经常访问parent,显然是第二种
WebService调用一对多关联关系时出现 死循环:A cycle is detected in...的更多相关文章
- webservice调用服务端数据时给soapenv:Envelope 添加自定义的命名空间
最近做第三方接口,服务端需要 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/&qu ...
- 使用XmlInclude解决WebService调用时无法识别子类的异常
一.定义抽象类及子类,WebMethod实际返回子类参数 //使用XmlInclude解决WebService调用时无法识别子类的异常 [System.Xml.Serialization.XmlInc ...
- JPA学习笔记(8)——映射双向一对多关联关系
双向一对多关联关系 前面的博客讲的都是单向的,而本问讲的是双向的(双向一对多 = 双向多对一) 什么是双向? 我们来对照一下单向和双向 单向/双向 User实体类中是否有List< Order& ...
- 使用自定义签名的https的ssl安全问题解决和metro的webservice调用
最近一直在忙新的项目,每天加班到8点多,都没来写博客了.新的项目遇到了很多问题,现在趁着突然停电来记录下调用https的问题吧. 我们服务主要是,我们调用数据源数据,并且再提供接口供外部数据调用. 我 ...
- C#动态webservice调用接口 (JAVA,C#)
C#动态webservice调用接口 using System; using System.Collections; using System.IO; using System.Net; using ...
- 怎样让webservice在浏览器远程浏览时像在本地浏览一样有参数输入框
从远程客户端访问服务器上的WebService能够显示,但点击调用相关的方法时显示“只能用于来自本地计算机的请求”,这时提醒我们还需要在服务器进行相关的配置才能让其他机器正常访问该WebService ...
- [原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- WebService 调用三种方法
//来源:http://www.cnblogs.com/eagle1986/archive/2012/09/03/2669699.html 最近做一个项目,由于是在别人框架里开发app,导致了很多限制 ...
- JPA 单向一对多关联关系
映射单向一对多的关联关系 1.首先在一的一端加入多的一端的实体类集合 2.使用@OneToMany 来映射一对多的关联关系3.使用@JoinColumn 来映射外键列的名称4.可以使用@OneToMa ...
随机推荐
- 第三方登录(1)OAuth(开放授权)简介及授权过程
3个角色:服务方,开发者,用户 a.用户在第在服务注册填写个人信息, b.服务方开放OAuth, c.开发者在服务方申请第3方登录,在程序中得到令牌后,经用户同意,可得到用户的个人信息. OAuth ...
- oracle创建表空间、创建用户、授权、夺权、删除用户、删除表空间
表空间定义 表空间是为了统一ORACLE物理和逻辑上的结构而专门建立的,从物理上来说,一个表空间是由具体的一个或多个磁盘上数据文件构成的(至少1对1,可以1对多),从逻辑上来说一个表空间是由具体的一个 ...
- Hibernate 的<generator class="native"></generator>的不同属性含义
1) assigned主键由外部程序负责生成,无需Hibernate参与. 2) hilo通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态. 3) seqhilo与hil ...
- CSS 中浮动的使用
float none 正常显示 left 左浮动 right 右浮动 clear none 允许两边浮动 left 不允许左边浮动 right 不允许右边浮动 both 不允许两边浮动 <!DO ...
- UVa401 回文词
Palindromes A regular palindrome is a string of numbers or letters that is the same forward as backw ...
- ajax连接数据库并操作数据库
Response.Write("<script type='text/javascript' language='javascript' >alert('用户名不能为空!请输入 ...
- MVC+Ef项目(4) 抽象业务逻辑层BLL层
接下来,我们就要到业务逻辑层了,简单的说,业务逻辑层就是调用Repository(可以看做是DAL数据库访问层) 先来看看项目的架构 我们现在就开始来做BLL层. 同样,先编写 UserInfoS ...
- LeetCode Reverse Nodes in k-Group 每k个节点为一组,反置链表
题意:给一个单链表,每k个节点就将这k个节点反置,若节点数不是k的倍数,则后面不够k个的这一小段链表不必反置. 思路:递归法.每次递归就将k个节点反置,将k个之后的链表头递归下去解决.利用原来的函数接 ...
- HDU 1247 Hat’s Words (字符串匹配,暴力)
题意: 给出一堆单词,如果有一个单词可以分成左右串两个单词,并且在所给的一堆单词中存在,就是hat词,统计所有这样的词,并按字典序输出. 思路: 注意定义,一个hat词可以被两部分已经存在的词组成,那 ...
- mysql,多表的内外连接+子查询
表: student house course 关系:student_course 多对多 student house 多对一 需求:查询房间1 的学生 都学习了什么课程 select s.s_nam ...