2012-01-27 60 views
24

我有這樣的雙向關係...Spring MVC的 - JSON無限遞歸

Person.java

public class Person{ 

    @JsonIgnore 
    @OneToMany(targetEntity=PersonOrganization.class, cascade=CascadeType.ALL, 
     fetch=FetchType.EAGER, mappedBy="person") 
    private Set<PeopleOrg> organization; 
    ..... 
} 

PersonOrganization.java

public class PersonOrganization{ 

    @JsonIgnore 
@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name="PERSONID", nullable=false) 
private Person person; 
    } 

即使@JsonIgnore註釋我嘗試檢索人員記錄時出現無限遞歸錯誤。我已經在1.6版本中嘗試了新的註釋。 @JsonBackReference@JsonManagedReference。即使這樣,我就Person@JsonManagedReference("person-organization")PersonOrganization

org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.entity.Person["organization"]->org.hibernate.collection.PersistentSet[0]->com.entity.PersonOrganization["person"]->com.entity.Person["organization"]->org.hibernate.collection.PersistentSet[0]... 

得到無限遞歸..

隨着@JsonBackReference("person-organization")即使我交換了註釋,我仍然得到此異常。請讓我知道如果有映射或我使用JSON註釋的方式有問題。謝謝

回答

38

我以前碰到過這個。但是將@JsonIgnore從私有字段移動到字段的獲得者之後,無限遞歸消失了。所以我瘋狂的猜測是@JsonIgnore可能無法在私人領域工作。但是,傑克遜Java JSON處理器的javadoc或教程沒有提到這一點,所以我不能100%確定。只是爲了您的信息。

+2

這也適用於我,但我找不到原因! – Skurpi 2012-03-30 12:41:30

+2

我現在可以給你一個大胖子的吻。這解決了我的問題。就我而言,該領域受到保護。 – theblang 2013-10-24 15:28:16

+0

這還不夠,我仍然有問題。 – 2016-06-01 10:11:24

10

以下鏈接指出您應該註釋JSON工具使用的方法來遍歷對象圖,以指示它忽略遍歷。

http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/annotate/JsonIgnore.html

在我來說,我有相關的這樣的產品<兩個對象 - > ProductImage。所以JSON解析器走進了與註釋@JsonIgnore一個無限循環以下獲得方法

@JsonIgnore 
public Product getImageOfProduct() { 
    return imageOfProduct; 
} 

在ProductImage和

@JsonIgnore 
public Set<ProductImage> getProductImages() { 
    return productImages; 
} 
在產品

通過註釋,事情工作正常。

+0

註解getter而不是爲我工作的領域。 WAS 8.5 JEE 6。 – 2013-12-03 05:33:18

5

我知道這個問題並不是專門針對Spring Data REST,但是我在Spring Data REST的上下文中遇到了這個異常,並且想要分享問題所在。我有一個涉及沒有存儲庫的實體的雙向關係。創建存儲庫使循環消失。

+0

我有兩個存儲庫,但我仍然有循環 – 2016-06-01 10:13:45

+1

我找到了解決方案:我們需要使用@ JsonManagedReference和@ JsonBackReference對投影(不在實體中) – 2016-06-01 10:28:57

4

由於Jackson 1.6可以使用兩個註釋來解決無限遞歸問題,而無需在序列化過程中忽略getters/setters:@JsonManagedReference和@JsonBackReference。

欲瞭解更多詳情,請參閱https://stackoverflow.com/a/18288939/286588

0

這可能是有點老了,但你可以在一流水平應該忽略所有屬性添加@JsonIgnore。即克

@JsonIgnore("productImaes","...") 
public class Product{ ... 
} 
0

有時構件字段可以具有內參照同一類類型本身,這可能導致無限遞歸toJson

例如:您有一個成員字段Klass a,而該Klass的類定義如下。

class Klass { 
    Klass mySibling; 

    public toString() { 
     return "something" + mySibling.whateverMethod; 
    } 
} 

解決方案:重構成員字段,消除內部引用。

-2

傑克遜通過調用getters來處理Reflection。我也有這樣一種情況,我在班上有同一個對象的getter。傑克遜通過反覆調用自己的getter來進入無限遞歸。刪除了getter,然後就修復了。

我的建議: 如果你想使用傑克遜的對象轉換,不要保留引用同一對象的getters,就像單例一樣。

0

顯然,自從傑克遜1.6以來,您可以使用@JsonManagedReference@JsonBackReference來有效解決無限遞歸問題。

我不會深入細節,但是這會將您的類更改爲以下格式應該可以解決問題。

public class Person{ 

    @OneToMany(targetEntity=PersonOrganization.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="person") 
    @Column(nullable = true) 
    @JsonManagedReference 
    private Set<PeopleOrg> organization; 
    ..... 
} 

public class PersonOrganization{ 

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinColumn(name="PERSONID") 
    @JsonBackReference 
    private Person person; 
    } 

基本上傑克遜轉換Set<PeopleOrg> organization,使用編組過程的一個參考的前部到類JSON格式時,它然後查找Person person,參考後面的部分和不序列它。

積分 - Kurt Bourbaki &更多信息 - http://keenformatics.blogspot.co.ke/2013/08/how-to-solve-json-infinite-recursion.html

0

這個異常是因爲,你的構造場不正確,請在你的類再次檢查你的構造屬性,並檢查映射給正確與否,

保留兩個構造函數,第一個是零構造,第二個構造函數是字段,兩者都應該包含超級

1

如果A有B & B有A.

這是一對一的關係,但是形成了一個循環關係。

在任何類中,都使用JustIgnore註釋。

class A 
{  
B b;  
} 

class B 
{  
@JsonIgnore 
A a; 
} 

這適用於其他關係也像一對多。