问题描述:
持久层框架用的是JPAhtml
在Controller返回JSON数据到前端的时候 出现了这个StackOverflowError的错误
即 在将对象转换为JSON格式的数据的时候出现了无限递归调用的状况
前端
以下:java
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: net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:296) at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:103) at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
缘由:
实体类之间互相关联 在序列化A实体类的时候 因为A里有B类 而后去序列化B 在序列化B实体类的时候 又因为B里有A类 而后去序列化A
如此反复递归 从而形成该问题
web
解决方法:
在有关联关系的属性的getter方法(请注意 是getter方法不是setter方法)上添加@JsonBackReference
或@JsonManagedReference
注解spring
- 在多的一方加上
@JsonBackReference
注解 - 而且在一的一方加上
@JsonManagedReference
注解
这两个注解一般是配对使用的
@JsonBackReference
注解标注的属性在序列化(serialization)的时候会被忽略 即结果中的json数据不包含该属性的内容
而@JsonManagedReference
注解标注的属性则会被序列化
apache
例一:json
@ManyToOne private Type type; @JsonBackReference public Type getType() { return type; } public void setType(Type type) { this.type = type; }
例二:tomcat
@OneToMany(mappedBy = "type") private List<User> users=new ArrayList<>(); @JsonManagedReference public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; }