以前遇到这个问题都是设下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这两个属性,重新启动服务了。 |