使用json-lib将对象转成json字符串发生的问题

使用Hibernate框架生成实体类转JSON数据时,因表间关联关系和Hibernate延迟加载会出现死循环。针对页面是否需要展示关联数据,分别给出解决办法,即排除关联对象属性或改为立即加载并排除关联对象属性,还列举了学生表和班级表的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Hibernate框架生成实体类后,经常会将实体类转换为json数据返回给前台页面。但是在转json的过程中由于表之间存在关联关系,由于Hibernate的延迟加载,所以会导致在转json的过程中会出死循环。具体错误如下:

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:657)
	at net.sf.json.JSONObject.fromObject(JSONObject.java:172)
	at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:274)
	at net.sf.json.JSONObject._processValue(JSONObject.java:2655)
	at net.sf.json.JSONObject.processValue(JSONObject.java:2721)
	at net.sf.json.JSONObject.setInternal(JSONObject.java:2736)
	at net.sf.json.JSONObject.setValue(JSONObject.java:1424)
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
	at net.sf.json.JSONObject._fromBean(JSONObject.java:699)
	at net.sf.json.JSONObject.fromObject(JSONObject.java:172)
	at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:274)
	at net.sf.json.JSONArray._processValue(JSONArray.java:2513)
	at net.sf.json.JSONArray.processValue(JSONArray.java:2538)
	at net.sf.json.JSONArray.addValue(JSONArray.java:2525)

............

一般会有如下两种情况会发生上面的错误。

  • 页面不需要展示关联数据时

解决:将关联对象属性排除掉

  • 页面需要展示关联数据时

解决:将关联对象改为立即加载,并且将关联对象中的属性排除


如下表关系:

学生表和班级表是多对一的关系。


生成的学生表的实体类:

public class Student {
    private String id;
    private String classId;
    private String name;
    private Interger gender;
    private TClass tclass; //一方
    //get、set方法省略
} 

学生表的hbm.xml部分:

        <many-to-one name="tclass" class="com.test.TClass" fetch="select">
            <column name="class_id" length="32" />
        </many-to-one> 

生成的班级表的实体类:

public class TClass{
    private String id;
    private String name;
    private Set student = new HashSet(0); //多方
} 

班级表的hbm.xml部分:

        <set name="student" inverse="true">
            <key>
                <column name="class_id" length="32" />
            </key>
            <one-to-many class="com.test.Student" />
        </set> 

当页面上只显示班级信息,不显示关联的学生信息时,

          //使用json-lib将TClass对象转为Json,通过输出流写回页面中
        JsonConfig jsonConfig = new JsonConfig();
        //指定哪些属性不需要转json
        jsonConfig.setExcludes(new String[]{"student"});
        String json = JSONObject.fromObject(tclass, jsonConfig).toString();
        ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
        ServletActionContext.getResponse().getWriter().print(json); 

当页面上在显示学生信息时,同时还要显示关联的班级信息

        //使用json-lib将TClass对象转为Json,通过输出流写回页面中
        JsonConfig jsonConfig = new JsonConfig();
        //指定哪些属性不需要转json
        jsonConfig.setExcludes(new String[]{"student"});
        String json = JSONObject.fromObject(tclass, jsonConfig).toString();
        ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
        ServletActionContext.getResponse().getWriter().print(json); 
    修改学生表对应的hbm.xml
        <many-to-one lazy="false" name="tclass" class="com.test.TClass" fetch="select">
            <column name="class_id" length="32" />
        </many-to-one> 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值