丈夫.java
package com.example.demo.com.example.domain; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; import javax.persistence.*; //@Data //@NoArgsConstructor //@EqualsAndHashCode //@ToString @Entity @Table(name = "t_husban") public class Husband { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private String job; @OneToOne @JoinColumn(name = "wife_fk",referencedColumnName = "id") private Wife wife; //omitted getter/setter }
妻子.java
package com.example.demo.com.example.domain; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; import javax.persistence.*; //@Data //@NoArgsConstructor @EqualsAndHashCode(exclude = "husband",callSuper = false) @Entity @Table(name = "t_wife") public class Wife { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; @OneToOne(mappedBy = "wife",cascade = {CascadeType.ALL}) private Husband husband; //omitted getter/setter }
Service.java
@Service public class TestOneToOneEitherSide { @Autowired private WifeRepository wifeDao; @Autowired private HusbandRepository husbandDao; public Husband testCreate() { Husband husband = husbandDao.findByName("Wang"); return husband; } }
当我使用spring数据jpa从数据库中查询丈夫时,结果发生无限递归,参见下图。使用@OneToOne注释时出了什么问题?有人可以给我一些建议吗?或者我以错误的方式使用了注释。
图片
这是一个已知问题,当您具有双向关系时,杰克逊将尝试从另一侧序列化一侧的每个引用,以便逻辑上具有无限递归。
解决方案:有很多解决方案,可以在一侧使用@JsonIgnore以避免序列化带注释的引用,从而破坏了无限递归
@EqualsAndHashCode(exclude = "husband",callSuper = false) @Entity @Table(name = "t_wife") public class Wife { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; @OneToOne(mappedBy = "wife",cascade = {CascadeType.ALL}) @JsonIgnore private Husband husband; //omitted getter/setter }
您也可以使用@ JsonManagedReference / @ JsonBackReference,请查看此链接以获取更多有关如何使用它们的信息
这个答案有一个问题,如果您尝试序列化妻子的方向,您将没有丈夫对象,因为解决方案是避免序列化它。
有一个很好的解决方案,它在此链接中提到,其思想是生成对父实体的引用,因此,如果您要序列化丈夫,您将拥有丈夫->妻子-> [引用丈夫而不是丈夫] ,您所需要做的就是使用@JsonIdentityInfo注释您的实体
@EqualsAndHashCode(exclude = "husband",callSuper = false) @Entity @Table(name = "t_wife") @JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id") public class Wife { @JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id") @Entity @Table(name = "t_husban") public class Husband { @Id