在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":[]}]