2013-01-11 124 views
2

我正在嘗試一些非常基本的webservice。每次我嘗試返回Prtnr對象時,都會收到此異常。org.codehaus.jackson.map.JsonMappingException:無限遞歸(StackOverflowError)

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

的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 

} 

的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 
} 

我相信這是因爲課程摺疊每個o療法。但是,這個問題怎麼解決。在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; 
    } 
} 

調用類是 公共類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()); 
    } 
} 

回答

-1

的無限遞歸是由於以下:Prtnr 類包含Set<PrtnrGeoInfo> prtnrGeoInfos和每個PrtnrGeoInfo包含PrtnrGeoInfoId id,其又包含Prtnr partner

因此,Prtnr - >PrtnrGeoInfo - >PrtnrGeoInfoId - >Prtnr,導致循環依賴其是用於傑克遜一個問題,當它試圖做POJO映射。

您需要刪除此循環依賴項來修復此異常。

+0

不幸的是,這是應用程序的要求,無法刪除。如何克服循環依賴問題? – user1860447

+0

我猜你可能在'PrtnrGeoInfoId'中需要的是'Prtnr'的一些實例變量。解決這個問題的唯一方法是從'PrtnrGeoInfoId'中刪除'Prtnr'。另外,想想如果你可以用其他類替換它。 – Srinivas

2

當您嘗試將實體類轉換爲JSON格式時,這對我來說是相當常見的情況。最簡單的解決方案就是在反向映射上使用@JsonIgnore來打破循環。

0

這是一個常見的序列化問題。 您必須在寫入xml或json或對象流時使用@Transient分解這些依賴項。

而你必須在閱讀的時候連線。 佈線在這樣的方法

class Way{ 
list nodes; 
addNode(Node node){ 
node.setWay(this); 
nodes.add(node); 

}

} 
2

您可以標註在PrtnrGeoInfoId與@JsonBackReference

5

Prtnr的第二個參考在此link你可以找到如何解決這件事。

但是,下面我將在實踐中粘貼解決方案。

這很簡單。假設你的數據庫查詢工作已經沒有JSON,所有你需要做的是這樣的:

添加@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",[email protected](name = "user_fk"), 
[email protected](name = "role_fk")) 
@JsonManagedReference 
private Set<Role> roles = new HashSet<Role>(); 

... 

添加@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>(); 

... 

的工作就完成了。如果你看看你的螢火蟲日誌,你會注意到無限遞歸循環已經消失。