我有以下关系:
我试图在Spring Boot中使用JPA映射这些关系,但我遇到了一些麻烦。这些是类:
人:
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Relations
@OneToOne
@JoinColumn(name = "child_id")
private PersonBirth birth;
@OneToMany
@JoinColumn(name = "mother_id")
private List<PersonBirth> motherOf;
@OneToMany
@JoinColumn(name = "father_id")
private List<PersonBirth> fatherOf;
}
PersonBirth:
public class Birth {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "birth_date")
@JsonProperty(value = "birth_date")
private Long birthDate;
// Relations
@OneToOne
@JoinColumn(name = "child_id")
private Person child;
@ManyToOne
@JoinColumn(name = "mother_id")
private Person mother;
@ManyToOne
@JoinColumn(name = "father_id")
private Person father;
}
我试图获得Pearson
及其Birth
数据,包括他的mother
和father
。并且也可以通过Person
或fatherOf
生成motherOf
其子项。但是它现在的方式,当我获取一个母亲Person
时,它会抛出stackoverflow,因为它获取Birth
数据,其中包含child
数据(到目前为止我是想要),包含他的Birth
数据,包含他的母亲,包含她的孩子(等等)。我不知道我尝试做什么是可能使用这种结构,或者我是否必须改变它......任何建议都值得赞赏。
答案 0 :(得分:0)
从您的描述中,我猜想在将结构序列化为JSON时会出现问题。如果您使用Jackson(这是Spring Boot的默认设置),您可以使用@JsonManagedReference
和@JsonBackReference
注释:
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Relations
@OneToOne
@JoinColumn(name = "child_id")
@JsonManagedReference("birth")
private PersonBirth birth;
@OneToMany
@JoinColumn(name = "mother_id")
@JsonManagedReference("mother")
private List<PersonBirth> motherOf;
@OneToMany
@JoinColumn(name = "father_id")
@JsonManagedReference("father")
private List<PersonBirth> fatherOf;
}
public class Birth {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "birth_date")
@JsonProperty(value = "birth_date")
private Long birthDate;
// Relations
@OneToOne
@JoinColumn(name = "child_id")
@JsonBackReference("birth")
private Person child;
@ManyToOne
@JoinColumn(name = "mother_id")
@JsonBackReference("mother")
private Person mother;
@ManyToOne
@JoinColumn(name = "father_id")
@JsonBackReference("father")
private Person father;
}
这样,杰克逊不会将整个对象序列化为后向引用,而只是标识符。
答案 1 :(得分:0)
只是添加@dunni回答的内容:
为了让Jackson运行良好,关系的两个方面之一不应该被序列化,以避免恼人的无限递归循环导致stackoverflow错误。
Jackson接受引用的前向部分,例如java类的属性(即User类中的List角色),并将其转换为类似json的存储格式;这就是所谓的编组过程。 然后,Jackson查找引用的后半部分(即在Role类中列出用户)并保持原样,而不是序列化它。在前向参考的反序列化(解组)过程中,将重新构建这部分关系。
参考: http://keenformatics.blogspot.com/2013/08/how-to-solve-json-infinite-recursion.html