现在的位置: 首页 > 综合 > 正文

net.sf.json.JSONException: There is a cycle in the hierarchy异常的解决方法

2013年10月10日 ⁄ 综合 ⁄ 共 2338字 ⁄ 字号 评论关闭

以前遇到这个问题都是设下JsonConfig 的一个属性的:config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

到后来才发现,这样不能从根源解决问题。后来在网上看到一个人写的博客,写的太棒了,转来跟大家分享下。

博客地址:http://chenjinglys.blog.163.com/blog/static/16657571620101010727123/

博客原文:

因为项目中使用了AJAX技术,JAR包为:json-lib.jar, 在开发过程中遇到了一个JSON-LIB和Hibernate有关的问题: 

net.sf.json.JSONException: There is a cycle in the hierarchy!
        at net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.
handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)
        at net.sf.json.JSONObject._fromBean(JSONObject.java:674)
        at net.sf.json.JSONObject.fromObject(JSONObject.java:181)
        at net.sf.json.JSONArray._processValue(JSONArray.java:2381)
        at net.sf.json.JSONArray.processValue(JSONArray.java:2412)
        Truncated. see log file for complete stacktrace
>

仔细查了一下发现是hibernate主外键关联的错,后来就想下json源代码下来看,发现大费周章都没搞到json源码,还是老办法反编译瞅瞅,发现JSONArray根据判断取得的不同类型调用相应的方法,

if (object instanceof Collection)
    return _fromCollection((Collection)object, jsonConfig);

而我从hibernate那得到的是list,所以去调用了_fromCollection方法,而里面的方法发现一个问题:该方法会不断的拆开实体属性,直到没有为止,而我的ContactGroup里有两个属性用于自身关联 

Iouser.hbm.xml: 
<many-to-one name="group" class="net.yanhl.iouser.pojo.GroupRelation" lazy="false" cascade="none"> 
<column name="group_id" /> 
</many-to-one> 
//设置自身关联的组对象 
public class GroupRelation implements Serializable { 
private static final long serialVersionUID = 6202253180943473205L; 
private Integer id;// 主键ID 
private Integer creatorId;// 创建人 
private Date createDate;// 创建日期 
private String groupName;// 组名称 
private GroupRelation parentGroup; 
private Set<GroupRelation> childGroups = new HashSet<GroupRelation>(); 
<many-to-one name="parentGroup" column="parent_id" lazy="false" 
class="net.yanhl.iouser.pojo.GroupRelation"> 
</many-to-one> 
<set name="childGroups" cascade="save-update" inverse="true"> 
<key column="parent_id"></key> 
<one-to-many class="net.yanhl.iouser.pojo.GroupRelation" /> 
</set> 
起初想通过hibernate来解决问题,就是想过滤掉自身关联后来查资料发现不可能实现,最后找到通过JSON-LIB来过滤关联的集合属性,代码如下: 
JsonConfig config = new JsonConfig(); 
config.setJsonPropertyFilter(new PropertyFilter(){ 
public boolean apply(Object source, String name, Object value) { 
if(name.equals("parentGroup") || name.equals("childGroups")) { 
return true; 
} else { 
return false; 


}); 

Iouser user = (Iouser) getBaseManager().get(Iouser.class, iouserId); 
JSONObject jsonObject = JSONObject.fromObject(user, config); 
当JSON-LIB解析JAVABEAN时过滤掉parentGroup、childGroups这两个属性,重新启动服务了。

抱歉!评论已关闭.