2012-01-27 45 views
24

tôi có mối quan hệ hai chiều như thế này ...Spring MVC - JSON đệ quy vô hạn

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

Ngay cả với @JsonIgnore chú thích tôi nhận được lỗi đệ quy vô hạn khi cố gắng truy xuất bản ghi Person. Tôi đã thử các chú thích mới trong phiên bản 1.6. @JsonBackReference@JsonManagedReference. Thậm chí sau đó tôi nhận được đệ quy vô hạn ..

Với @JsonBackReference("person-organization") trên Person@JsonManagedReference("person-organization") trên 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]... 

Ngay cả Nếu tôi trao đổi các chú thích, tôi vẫn nhận được ngoại lệ này .. Xin vui lòng cho tôi biết nếu có có điều gì đó sai với ánh xạ hoặc cách tôi đang sử dụng chú thích JSON. Cảm ơn

Trả lời

38

Tôi đã thực hiện điều này trước đây. Nhưng sau khi di chuyển @JsonIgnore từ trường riêng sang getter của trường, đệ quy vô hạn đã biến mất. Vì vậy, dự đoán hoang dã của tôi là @JsonIgnore có thể không hoạt động trên trường riêng tư. Tuy nhiên, javadoc hoặc hướng dẫn của bộ xử lý JSON Java Java không đề cập đến điều này, vì vậy tôi không thể chắc chắn 100%. Chỉ cần cho thông tin của bạn.

+2

Điều này cũng phù hợp với tôi, tuy nhiên tôi không thể tìm hiểu lý do tại sao! – Skurpi

+2

Tôi có thể cho bạn một nụ hôn béo lớn ngay bây giờ. Điều này đã khắc phục được sự cố của tôi. Trong trường hợp của tôi, lĩnh vực này đã được bảo vệ. – theblang

+0

Không đủ, tôi vẫn gặp vấn đề. –

10

Liên kết sau cho biết bạn nên chú thích phương thức được sử dụng bởi công cụ JSON để duyệt qua biểu đồ đối tượng, để hướng dẫn nó bỏ qua quá trình truyền tải.

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

Trong trường hợp của tôi, tôi có hai đối tượng liên quan như sản phẩm này < -> ProductImage. Vì vậy, JSON phân tích cú pháp đi vào một vòng lặp vô hạn với chú thích @JsonIgnore ra trên sau đây để có được phương pháp

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

trong ProductImage và

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

trong sản phẩm.

Với chú thích, mọi thứ đang hoạt động tốt.

+0

Chú thích trình khởi động thay vì trường làm việc cho tôi. WS 8,5 JEE 6. –

5

Tôi biết câu hỏi này không cụ thể về REST dữ liệu mùa xuân, nhưng tôi đã chạy vào ngoại lệ này trong ngữ cảnh của Spring Data REST và muốn chia sẻ vấn đề là gì. Tôi đã có một mối quan hệ hai chiều liên quan đến một thực thể không có kho lưu trữ. Tạo kho lưu trữ khiến vòng lặp biến mất.

+0

Tôi có cả hai kho lưu trữ, nhưng tôi vẫn có vòng lặp –

+1

Tôi đã tìm thấy giải pháp: chúng tôi cần sử dụng @ JsonManagedReference và @ JsonBackReference trên các Phép chiếu (KHÔNG phải trong các quyền lợi) –

4

Vì Jackson 1.6 bạn có thể sử dụng hai chú thích để giải quyết vấn đề đệ quy vô hạn mà không bỏ qua getters/setters trong quá trình tuần tự hóa: @JsonManagedReference và @JsonBackReference.

Để biết thêm thông tin chi tiết tham khảo https://stackoverflow.com/a/18288939/286588

0

Điều này có thể ít tuổi nhưng bạn có thể thêm @JsonIgnore ở cấp lớp với tất cả các thuộc tính nó nên bỏ qua. e.g

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

Đôi khi các trường thành viên có thể tham khảo bên trong để loại cùng lớp của chính nó, mà có thể gây ra đệ quy vô hạn khi toJson.

Ví dụ: bạn có trường thành viên Klass a, trong khi định nghĩa lớp của Klass đó như sau.

class Klass { 
    Klass mySibling; 

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

Giải pháp: refactor trường thành viên, loại bỏ tham chiếu bên trong.

-2

Jackson hoạt động trên Reflection bằng cách gọi getters. Tôi cũng đã có một tình huống như vậy, nơi tôi đã có một getter của cùng một đối tượng bên trong lớp học của nó. Jackson đã đi vào vô hạn đệ quy ăn lên stack bằng cách liên tục gọi getter riêng của mình. Loại bỏ getter, sau đó nó đã được cố định.

Lời khuyên của tôi: Nếu bạn muốn sử dụng jackson để chuyển đổi một đối tượng, không bao giờ giữ getters tham chiếu cùng một đối tượng, như trong trường hợp đơn.

0

Rõ ràng kể từ khi Jackson 1.6 bạn có thể sử dụng @JsonManagedReference@JsonBackReference để giải quyết hiệu quả vấn đề đệ quy vô hạn.

Tôi sẽ không đi sâu vào chi tiết nhưng việc thay đổi lớp học của bạn thành định dạng dưới đây sẽ giải quyết được vấn đề.

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

Về cơ bản Jackson chuyển đổi Set<PeopleOrg> organization, phần phía trước của tham chiếu một sang định dạng json giống như sử dụng quá trình marshalling, nó sau đó tìm kiếm Person person, phần sau của tài liệu tham khảo và không serialize nó.

Tín - Kurt Bourbaki & Thông tin thêm - http://keenformatics.blogspot.co.ke/2013/08/how-to-solve-json-infinite-recursion.html

0

ngoại lệ này là bởi vì, lĩnh vực xây dựng của bạn không phù hợp, xin vui lòng kiểm tra tính nhà thầu của bạn một lần nữa trong lớp học của bạn, và kiểm tra lập bản đồ cho đúng cách hay không,

Giữ hai Constructors, đầu tiên là zero xây dựng và thứ hai constructor là với các lĩnh vực và cả hai nên được chứa các siêu

1

Nếu A có B & B có A.

Đây là một mối quan hệ, nhưng tạo thành mối quan hệ tròn.

Trong bất kỳ lớp nào, hãy sử dụng chú thích JustIgnore.

class A 
{  
B b;  
} 

class B 
{  
@JsonIgnore 
A a; 
} 

Điều này áp dụng cho các mối quan hệ khác cũng như từ một đến nhiều.

Các vấn đề liên quan