博客项目踩坑-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列表也序列化,这样就会发生死循环的问题。
经上网百度,要解决这个问题,有如下几种思路

  1. BlogType属性的get方法上加上@JsonBackReference注解,表示序列化时忽略type属性。
  2. 重新修改代码,避免循环引用。
  3. BlogType属性的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.