Java org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflower错误)
我正在尝试一些非常基本的Web服务。每次尝试返回Prtnr对象时都会出现此异常Java org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflower错误),java,web-services,hibernate,Java,Web Services,Hibernate,我正在尝试一些非常基本的Web服务。每次尝试返回Prtnr对象时都会出现此异常 Uncaught exception thrown in one of the service methods of the servlet: spitter. Exception thrown : org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference ch
Uncaught exception thrown in one of the service methods of the servlet: spitter. Exception thrown :
org.codehaus.jackson.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.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:164)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
...
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
...
}
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
}
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
}
PrtnrGeoInfoId类是:
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
...
}
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
}
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
}
我相信这是因为班级之间相互重复。但如何解决这个问题呢。在Struts 2和Spring应用程序中,这个对象可以很好地传递
控制器类如下所示:
@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;
}
}
调用类是
公共类测试模板
{
无限递归的原因如下: 类
Prtnr
包含Set prtnrGeoInfos
,每个PrtnrGeoInfo
包含PrtnrGeoInfoId id
,后者依次包含Prtnr合作伙伴
因此,Prtnr
->PrtnrGeoInfo
->PrtnrGeoInfoId
->Prtnr
,在Jackson尝试进行POJO映射时,会导致循环依赖性,这是一个问题
您需要删除此循环依赖项来修复此异常。当您尝试将实体类转换为JSON格式时,这对我来说是一个非常常见的场景。最简单的解决方案就是在反向映射上使用
@JsonIgnore
来打破循环。这是一个常规序列化问题。
在写入xml、json或对象流时,必须使用@Transient打破这些依赖关系
你必须在阅读时把它们接回去。
接线是用这种方法完成的
class Way{
list nodes;
addNode(Node node){
node.setWay(this);
nodes.add(node);
}
您可以使用
@JsonBackReference
在PrtnrGeoInfoId中注释Prtnr的第二个引用,在这里您可以找到解决方法
不过,下面我将实际粘贴解决方案
这很简单。假设您的数据库查询已经可以在没有JSON的情况下运行,那么您需要做的就是:
将@jsonmanagedreference
e添加到关系的前向部分(即User.java类):
工作完成了。如果您查看firebug日志,您会注意到无限递归循环已消失。不幸的是,这是应用程序的要求,无法删除。如何克服循环依赖性问题?我猜您在
PrtnrGeoInfoId
中需要的可能是Prtnr
的一些实例变量。克服这一问题的唯一方法是从PrtnrGeoInfoId
中删除Prtnr
。另外,请考虑是否可以用其他类替换该类。如果我们使用@JsonIgnore
,那么我们无法获取关联的实体数据,我们如何获取该数据?
@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>();
...