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

以前遇到這個問題都是設下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這兩個屬性,重新啓動服務了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章