Hibernate框架下使用Gson遇到StackOverflowError时如何解决

在hibernate框架下,我们经常会遇到使用多对多映射,比如学生和选修课、项目和成员等等。在这时候想把一个放着学生的List集合转换成JSON对象时,容易遇到StackOverFlowError。

Exception in thread "main" java.lang.StackOverflowError
at sun.util.locale.provider.LocaleProviderAdapter.getAdapter(LocaleProviderAdapter.java:243)
at java.text.DateFormatSymbols.getProviderInstance(DateFormatSymbols.java:357)
at java.text.DateFormatSymbols.getInstance(DateFormatSymbols.java:335)
at java.util.Calendar.getDisplayName(Calendar.java:2110)
at java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1125)

  ......

这个异常是怎么产生的呢,原因是在双向多对多映射会在各自的实体类中只有对方的集合,这样在进行序列化的时候会导致互相引用,学生类要引用课程类,到课程类又要引用学生类,最后导致死循环。

想要解决这个异常很简单,互相引用只要在序列化的时候忽略一种对另一种的引用,这样就不会导致无限循环引用,这时候就需要使用transient这个关键字了,在对象进行序列化的时候忽略被transient标识的成员变量,所以只要在任意一方的引用上加上transient关键字,就可以避免发生这个错误了。或者可以搜索Gson如何忽略某个属性也可以解决这个问题。下面附上代码。

课程实体类:

@Entity
@Table(name = "course")
public class Course implements Serializable{
    private int id;                     //主键id
    private Integer cid;                //课程号
    private String cname;               //课程名
    private Double credit;              //学分
    private Double period;              //课时
    private transient Teacher teachers;           //与老师类是一对多映射
    private transient Set
   
   
    
     students;      //与学生是多对多映射
    
    此处省略了setter和getter方法
}
   
   

学生实体类:
@Entity
@Table(name = "course")
public class Course implements Serializable{
    private int id;                     //主键id
    private Integer cid;                //课程号
    private String cname;               //课程名
    private Double credit;              //学分
    private Double period;              //课时
    private transient Teacher teachers;           //与老师类是一对多映射
    private transient Set
    
    
     
      students;      //与学生是多对多映射
    
    此处省略了setter和getter方法
}
    
    

测试类:
public class GsonTest {
    public static void main(String[] args) {
        StudentDAOImpl studentDAO = new StudentDAOImpl();
        Gson gson = new Gson();
        List
     
     
      
       studentList = new ArrayList<>();
        Student student1 = studentDAO.findStudentByID(4);
        Student student2 = studentDAO.findStudentByID(5);
        studentList.add(student1);
        studentList.add(student2);
        String json = gson.toJson(studentList);
        System.out.println(json);
    }
}
     
     

输出结果:

[{"id":4,"sno":201419229,"sname":"曾卓","password":"123456","gender":"男","age":21,"phone":"13000000000","year":"六月 10, 1995",
"courses":[{"id":1,"cid":1,"cname":"高数","credit":4.0,"period":64.0}]},
{"id":5,"sno":201419228,"sname":"小王","password":"123456","gender":"男","age":20,"phone":"13200000000","year":"一月 22, 1997","courses":[]}]




评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值