org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflowError) [英] org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError)

查看:1790
本文介绍了org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflowError)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试一些非常基本的web服务。每次我尝试返回Prtnr对象时,都会收到此异常。

 在servlet的服务方法之一中抛出的未捕获的异常:spitter。抛出异常:
org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflowError)
(通过引用链:org.hibernate.collection.PersistentSet [0] - > org.abc.dvo。 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] - >
...
在org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:164)
at org .codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)$ or $ $ b $ org.cod ehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
在org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
。 ..

Prtnr类是:

  public class Prtnr实现Cloneable,java.io.Serializable {

private static final long serialVersionUID = 201207021420600052L;
私人整数prtnrId;
private String creatUserId;
私人日期creatTs;
private String updtUserId;
私人日期updtTs;
私人字符串prtnrNm;
私人整数cncilNum;
私人字符prtnrTypCd;
私人套餐< PrtnrGeoInfo> prtnrGeoInfos = newHashSet< PrtnrGeoInfo>(0);
私人套餐< PrtnrDtl> prtnrDtls = new HashSet< PrtnrDtl>(0);
私人套餐< SuplyDtl> suplyDtls = new HashSet< SuplyDtl>(0);
private Set< TrnsprtDtl> trnsprtDtls = new HashSet< TrnsprtDtl>(0);
私人套餐< PrtnrFacil> prtnrFacils = new HashSet< PrtnrFacil>(0);
private Set< PrtnrHumanResrc> prtnrHumanResrcs = new HashSet< PrtnrHumanResrc>(0);
.....
.....
这些属性的获取者和设置者
...
}



PrtnrGeoInfo类为:

  public class PrtnrGeoInfo实现java.io.Serializable {
private PrtnrGeoInfoId id = new PrtnrGeoInfoId();
private String creatUserId;
私人日期creatTs;
private String updtUserId;
私人日期updtTs;

这些属性的获取者和设置者

}



< PrtnrGeoInfoId类是:

  public class PrtnrGeoInfoId implements java.io.Serializable {
private Prtnr partner;
私人GeoSegment地理区段;
private static final long serialVersionUID = 201207060857580050L;

这些属性的获取者和设置者
}

我相信这是因为这些班级彼此相互融合。但是,这个问题怎么解决。在Struts 2和Spring的应用程序中,这个对象得到了很好的传递。



控制器类如下所示:

  @Controller 
@RequestMapping(/ partners)
公共类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;
尝试{
partner = partnerService.getPartnerById(Integer.valueOf(id));
System.out.println(*******测试消息);
} catch(Exception ex){
System.out.println(******* Exception thrown ...+ ex.getMessage());
}

退货合作伙伴;


$ / code>

调用类是
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.getPrtnrNm());
}
}


解决方案

这个链接,你可以找到如何解决这个问题。



然而,下面我将在实践中粘贴该解决方案。



这非常简单。假设你的数据库查询已经可以在没有JSON的情况下运行,你只需要这样做:



添加 @JsonManagedReferenc e在关系的前面部分(即User.java类):

  @Entity 
public class User implements java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
私有长ID;

@Column(name =name)
私有字符串名称;

@ManyToMany
@JoinTable(name =users_roles,joinColumns = @ JoinColumn(name =user_fk),
inverseJoinColumns = @ JoinColumn(name =role_fk) )
@JsonManagedReference
私人设置< Role> roles = new HashSet< Role>();

...

添加 @JsonBackReference 在关系的后面(即Role.java类):

  @Entity 
public class Role实现java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@ManyToMany(mappedBy =roles)
@JsonBackReference
private Set< User> users = new HashSet< User>();

...

工作完成。如果你看看你的萤火虫日志,你会注意到无限递归循环已经消失。


I am trying out some very basic webservice. I get this exception everytime I try to return the Prtnr object.

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)
    ...

The Prtnr class is :

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 :

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 :

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.

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 {

    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());
    }
}

解决方案

In this link you 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:

Add the @JsonManagedReference In the forward part of the relationship (i.e. User.java class):

@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):

@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.

这篇关于org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflowError)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆