博客项目踩坑-Could not write JSON: Infinite recursion (StackOverflowError)
Posted Kira~~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了博客项目踩坑-Could not write JSON: Infinite recursion (StackOverflowError)相关的知识,希望对你有一定的参考价值。
之前用SpringBoot+JPA+Thymeleaf
的方式开发过一个博客系统,现在想要将博客系统改造成前后端分离的方式(前端Vue,后端SpringBoot),开发过程中遇到Could not write JSON: Infinite recursion (StackOverflowError)
的问题。
控制台报错如下:
于是检查Network控制台,发现从后端获取到的数据过大,博客系统真正的数据传输量应该远小于这些值
控制台报错信息如下(部分):
org.springframework.http.converter.HttpMessageNotWritableException:
Could not write JSON: Infinite recursion (StackOverflowError);
nested exception is com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (StackOverflowError) (through reference chain:
com.example.blog2.po.Blog["type"]->
com.example.blog2.po.Type["blogs"]->
org.hibernate.collection.internal.PersistentBag[0]->
com.example.blog2.po.Blog["type"]->
com.example.blog2.po.Type["blogs"]->
org.hibernate.collection.internal.PersistentBag[0]
于是便想到了是不是系统返回数据的过程中出现了死循环的问题,通过分析控制台的报错信息,不难看出,是因为type和blogs之间出现了循环引用才导致的死循环。
在Blog类中,通过以下方式引用了Type类
@ManyToOne
private Type type;
而在Type类中则引用着一个博客列表
@OneToMany(mappedBy = "type")
private List<Blog> blogs = new ArrayList<>();
这样的引用方式可以方便地实现数据库中一对多关系的映射,将t_type的id属性作为外键写入t_blog中,但在将数据传给前端时,需要将数据进行Json序列化,由于相互引用的原因,序列化Blog时也会序列化Type类,但因为Type类中有blog列表的引用,便会将blog列表也序列化,这样就会发生死循环的问题。
经上网百度,要解决这个问题,有如下几种思路
- 在
Blog
中Type
属性的get
方法上加上@JsonBackReference
注解,表示序列化时忽略type属性。 - 重新修改代码,避免循环引用。
- 在
Blog
中Type
属性的get
方法上加上@JsonIgnoreProperties({ "blogs"})
注解,传blog
对象时,忽略Type
中的Blogs
列表属性。
由于前端需要的得到blog关联的type属性,而采用第一种方式则无法得到type属性的信息,因此第一种方式不可行,而重新修改代码又会使JPA的功能达不到充分的利用,因此选用第二种方式也不合理。
在第三种方式中,忽略博客Type属性中的Blog列表属性,从而切断了循环引用,同时也保留了必要的信息,是目前解决StackOverflowError问题的最优解。
以上是关于博客项目踩坑-Could not write JSON: Infinite recursion (StackOverflowError)的主要内容,如果未能解决你的问题,请参考以下文章
博客项目踩坑-Could not write JSON: Infinite recursion (StackOverflowError)
docker 踩坑笔记之 psql: could not connect to server
Could not write file: C:.......classpath
Eclipse报错could not write metadata for '/xxx'
spring | 踩坑 | Could not get JDBC Connectionl nested exception is java.sql.SQLException...
hadoop运行踩坑:Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.