[Spring Data JPA] 例外:[Could not write JSON: Infinite recursion (StackOverflowError)的解决方法

错误提示:


2020-04-23 22:50:53.363  WARN 11316 --- [nio-8001-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Failure while trying to resolve exception [org.springframework.http.converter.HttpMessageNotWritableException]

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
	at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.sendServerError(DefaultHandlerExceptionResolver.java:550) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable
	......
2020-04-23 22:50:53.395 ERROR 11316 --- [nio-8001-exec-1] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/user/users] and exception [Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection.internal.PersistentBag[0]->com.itzhiya.first.jpa.demo.users.UserEntity["books"]-......

错误分析:
在将数据转为JSON返回时,出现了StackOverflowError,说明数据陷入了死循环。
原因如下:类A中有属性类型为List b;类A与类B为多对多的关系,当类B中没有类型为List的属性时,数据正常返回,但是当类B中存在A的List时,程序陷入死循环。因此判定,当程序从A中获取B的List时,系统会去B中,但是B中也有A中,于是系统又去A中执行,于是递归形成环路,导致系统陷入死循环。

解决方法:
1. 避免代码中互相包含

a)删除A或者B中其中一个属性
b) 在允许序列化的属性上使用@JsonManagedReference,另一个类中属性上使用@JsonBackReference,但是这样一来标注@JsonBackReference的属性将不会被序列化,即它的值不会被返回。

2. 无法避免代码中互相包含的情况

有时候根据需求,我们需要从A中获取B的信息,同时也需要从B中获取A的信息,这种情况下,可以在任意一个类中的属性上增加下面注解:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = “uid”)

这里uid为属性对应的对象表中的主键名称

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码界领航

你的鼓励将是我最最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值