java org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflowError)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14281541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
org.codehaus.Hymanson.map.JsonMappingException: Infinite recursion (StackOverflowError)
提问by user1860447
I am trying out some very basic webservice. I get this exception everytime I try to return the Prtnr object.
我正在尝试一些非常基本的网络服务。每次我尝试返回 Prtnr 对象时都会遇到此异常。
Uncaught exception thrown in one of the service methods of the servlet: spitter. Exception thrown :
org.codehaus.Hymanson.map.JsonMappingException: Infinite recursion (StackOverflowError)
(through reference chain: org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
org.abc.dvo.Prtnr["prtnrGeoInfos"]->org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
org.abc.dvo.Prtnr["prtnrGeoInfos"]->org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
org.abc.dvo.Prtnr["prtnrGeoInfos"]->org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
...
at org.codehaus.Hymanson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:164)
at org.codehaus.Hymanson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at org.codehaus.Hymanson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
at org.codehaus.Hymanson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
...
The Prtnr class is :
Prtnr 类是:
public class Prtnr implements Cloneable, java.io.Serializable {
private static final long serialVersionUID = 201207021420600052L;
private Integer prtnrId;
private String creatUserId;
private Date creatTs;
private String updtUserId;
private Date updtTs;
private String prtnrNm;
private Integer cncilNum;
private Character prtnrTypCd;
private Set<PrtnrGeoInfo> prtnrGeoInfos = new HashSet<PrtnrGeoInfo>(0);
private Set<PrtnrDtl> prtnrDtls = new HashSet<PrtnrDtl>(0);
private Set<SuplyDtl> suplyDtls = new HashSet<SuplyDtl>(0);
private Set<TrnsprtDtl> trnsprtDtls = new HashSet<TrnsprtDtl>(0);
private Set<PrtnrFacil> prtnrFacils = new HashSet<PrtnrFacil>(0);
private Set<PrtnrHumanResrc> prtnrHumanResrcs = new HashSet<PrtnrHumanResrc>(0);
.....
.....
Getters and setters for these properties
...
}
The PrtnrGeoInfo class is :
PrtnrGeoInfo 类是:
public class PrtnrGeoInfo implements java.io.Serializable {
private PrtnrGeoInfoId id = new PrtnrGeoInfoId();
private String creatUserId;
private Date creatTs;
private String updtUserId;
private Date updtTs;
Getters and setters for these properties
}
The PrtnrGeoInfoId class is :
PrtnrGeoInfoId 类是:
public class PrtnrGeoInfoId implements java.io.Serializable {
private Prtnr partner;
private GeoSegment geoSegment;
private static final long serialVersionUID = 201207060857580050L;
Getters and setters for these properties
}
I believe it is because of the classes refrencing each other. But how can this problem be resolved. Within the app which is Struts 2 and Spring, this object get passed just fine.
我相信这是因为类相互引用。但是这个问题怎么解决。在 Struts 2 和 Spring 的应用程序中,这个对象被传递得很好。
The controller class is as follows:
控制器类如下:
@Controller
@RequestMapping("/partners")
public class PartnerController {
@RequestMapping(value="/{id}", method=RequestMethod.GET, headers ={"Accept=text/xml,application/json"})
@ResponseBody
public Prtnr getPartner(@PathVariable("id") String id) throws Exception{
Prtnr partner = null;
try{
partner = partnerService.getPartnerById(Integer.valueOf(id));
System.out.println("******* Test message " );
}catch(Exception ex){
System.out.println("******* Exception thrown ... " + ex.getMessage());
}
return partner;
}
}
The calling class is public class TestTemplate {
调用类是 public class TestTemplate {
private static final long serialVersionUID = 1130201273334264152L;
public static void main(String[] args){
Prtnr partner = (Prtnr)new RestTemplate().getForObject("http://localhost:9080/respondersApp/testWs/partners/{id}", Prtnr.class, "1");
System.out.println("partner name is : " + partner.getPrtnrNm());
}
}
回答by madx
In this linkyou can find how to solve this.
在此链接中,您可以找到解决此问题的方法。
However below I'll paste the solution in practice.
但是,下面我将在实践中粘贴解决方案。
It's very simple. Assuming that your database query already works without JSON, all you have to do is this:
这很简单。假设您的数据库查询已经在没有 JSON 的情况下工作,您所要做的就是:
Add the @JsonManagedReferenc
e In the forward part of the relationship (i.e. User.java class):
@JsonManagedReferenc
在关系的前向部分添加e(即User.java类):
@Entity
public class User implements java.io.Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@Column(name="name")
private String name;
@ManyToMany
@JoinTable(name="users_roles",joinColumns=@JoinColumn(name = "user_fk"),
inverseJoinColumns=@JoinColumn(name = "role_fk"))
@JsonManagedReference
private Set<Role> roles = new HashSet<Role>();
...
Add the @JsonBackReference
In the back part of the relationship (i.e. Role.java class):
添加@JsonBackReference
关系的后面部分(即Role.java类):
@Entity
public class Role implements java.io.Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToMany(mappedBy="roles")
@JsonBackReference
private Set<User> users = new HashSet<User>();
...
The work is done. If you take a look at your firebug logs, you'll notice that the infinite recursive loop has disappeared.
工作完成了。如果您查看萤火虫日志,您会注意到无限递归循环已经消失。
回答by tarka
This is quite a common scenario for me when you are trying to convert entity classes into JSON format. The simplest solution is just to use @JsonIgnore
on the reverse mapping to break the cycle.
当您尝试将实体类转换为 JSON 格式时,这对我来说是一个很常见的场景。最简单的解决方案就是@JsonIgnore
在反向映射上使用来打破循环。
回答by user788052
You can annotate the second reference of Prtnr in PrtnrGeoInfoId with @JsonBackReference
您可以在 PrtnrGeoInfoId 中注释 Prtnr 的第二个引用 @JsonBackReference
回答by hans wurst
this is a general serializing issue. you have to break those dependencies using @Transient while writing to xml or json or object stream.
这是一个一般的序列化问题。在写入 xml 或 json 或对象流时,您必须使用 @Transient 打破这些依赖关系。
and you have to wire them back while reading. wiring is done in such method
你必须在阅读时将它们连接回去。接线是用这种方法完成的
class Way{
list nodes;
addNode(Node node){
node.setWay(this);
nodes.add(node);
}
}
}
回答by Srinivas
The infinite recursion is due to the following:
Class Prtnr
contains Set<PrtnrGeoInfo> prtnrGeoInfos
and each PrtnrGeoInfo
contains PrtnrGeoInfoId id
which in turn contains Prtnr partner
.
无限递归是由于以下原因: Class Prtnr
containsSet<PrtnrGeoInfo> prtnrGeoInfos
和 each PrtnrGeoInfo
contains PrtnrGeoInfoId id
,而每个contains又包含Prtnr partner
.
Thus, Prtnr
-> PrtnrGeoInfo
->PrtnrGeoInfoId
->Prtnr
, is causing a cyclic dependency which is a problem for Hymanson when it is trying to do the POJO Mapping.
因此,Prtnr
-> PrtnrGeoInfo
-> PrtnrGeoInfoId
->Prtnr
会导致循环依赖,这对于 Hymanson 尝试进行 POJO 映射时是个问题。
You need to remove this cyclic dependency to fix this exception.
您需要删除此循环依赖项以修复此异常。