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