使用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 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。 当我序列化一个Parent对象时,我得到以下JSON:

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

但是当我序列化一个Child时,我得到以下JSON:

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

缺少对父项的引用。 有办法解决这个问题吗?

我想你必须在@JsonIdentityInfo和@JsonBackReference / @JsonManagedReference之间进行选择。

我会在你的实体上使用:@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property =“id”),删除@JsonBackReference / @JsonManagedReference对。

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

您可以使用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 answers = new HashSet<>(); 

在回答Class://与问题的双向多对一关联

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

如果您需要在子对象中进行父引用,请删除Managed / Back Reference,这对我来说很好。

问题是使用托管/反向引用要求遍历的方向始终是从父级到子级(即,首先使用托管引用)。 这是对这些注释的限制。

正如另一个答案所暗示的那样,使用Object Ids是可能更灵活的替代方案。

另一个可能有用的选项是使用JSON视图或JSONfilter来有条件地包含/排除父引用,如果您可以分离案例。 这可能会变得混乱。

您可以使用@JsonBackReference / @ JsonManagedReference并将此方法添加到child

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

结果将是:

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

我希望这可以帮助别人。