2014-03-24 37 views
13

我使用Jackson將我的JPA模型序列化爲JSON。使用jackson將雙向JPA實體序列化爲JSON

我有以下類別:

import com.fasterxml.jackson.annotation.*; 
import javax.persistence.*; 
import java.util.Set; 

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class) 
@Entity 
public class Parent { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    private String name; 

    @JsonManagedReference 
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Set<Child> children; 

    //Getters and setters 
} 

import com.fasterxml.jackson.annotation.*; 
import javax.persistence.*; 
import java.util.HashSet; 
import java.util.Set; 

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class) 
@Entity 
public class Child { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    private String name; 

    @JsonBackReference 
    @ManyToOne 
    @JoinColumn(name = "parentId") 
    private Parent parent; 

    //Getters and setters 
} 

我使用POJO映射序列化從模型到JSON。當我序列化父對象,我得到以下JSON:

{ 
    "id": 1, 
    "name": "John Doe", 
    "children": [ 
    { 
     "id": 1, 
     "name": "child1" 
    },{ 
     "id": 2, 
     "name": "child2" 
    } 
    ] 
} 

但是,當我序列化一個孩子,我得到下面的JSON:

{ 
    "id": 1, 
    "name": "child1" 
} 

父參考丟失。 有沒有辦法解決這個問題?

+0

包含UI相關邏輯,例如json註釋在實體中是不是很糟糕?它不是在殺死模塊化嗎? – faisalbhagat

+3

呃...不。這就是實體存在的主要原因:作爲數據模型表示,無論是JPA,XML,JSON,還是其組合。讓您的整個應用程序使用單個實體集合是設計良好的應用程序的指標 - 一組實體會導致單點故障,從而使應用程序可維護(並可交換)的程度更高。 – specializt

回答

24

我想你必須在@JsonIdentityInfo和@ JsonBackReference/@ JsonManagedReference之間進行選擇。

我會去:@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property =「id」)在您的實體上,刪除@ JsonBackReference/@ JsonManagedReference對。

並在要排除的字段上添加@JsonIgnore。

3

問題是,使用託管/返回引用要求遍歷的方向總是從父到子(即先使用託管引用)。這是對這些註釋的限制。

正如其他答案所暗示的那樣,使用Object Ids是更靈活的替代方案,可能可行。

另一個可能可行的選擇是使用JSON視圖或JSON過濾器來有條件地包含/排除父引用(如果可以分開的話)。這可能會變得混亂。

5

您可以使用JsonManagedReference/JsonBackReference並同時使用JsonIdentityInfo來補充雙向關係。

問題類別:

// bi-directional one-to-many association to Answer (Question is owner) 
@JsonManagedReference 
@OneToMany(mappedBy = "question", cascade = CascadeType.ALL) 
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@QuestionAnswers") 
private Set<Answer> answers = new HashSet<>(); 

在回答類別: //雙向多到一個如果你需要在子對象的父引用聯想到問題

@JsonBackReference 
@ManyToOne 
@JoinColumn(name = "questionId", referencedColumnName="id", foreignKey = @ForeignKey(name = "fk_answer_question")) 
private Question question; 

,刪除託管/後臺引用,這對我來說很好。

+0

什麼是財產=「@QuestionAnswers」?據我瞭解,這些課程的名稱是答案和問題 – Aditzu

+0

同時使用兩個都沒有爲我做任何事情。 @ JsonManagedReference/BackReference似乎覆蓋@JsonIdentityInfo。 –

1

您可以使用@ JsonBackReference/@ JsonManagedReference這種方法添加到孩子

@JsonProperty 
public Long getParentId() { 
    return parent == null ? null : parent.getId(); 
} 

結果將是:

{ 
    "id": 1, 
    "name": "child1", 
    "parentId": 1 
} 

我希望這可以幫助別人。

相關問題