Hibernate一对一双向混淆

Hibernate one to one bidirectional confusion

我有示例代码来检查双向关系是如何工作的。

@Getter
@Setter
@NoArgsConstructor
@ToString
@Entity
public class A {
   @Id
   @GeneratedValue
   private long aId;
    String name;
    String address;
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "b_id_FK")
    B b;
}

@Getter
@Setter
@NoArgsConstructor
@ToString
@Entity
public class B {
    @Id
    @GeneratedValue
    @Column(name = "b_id_PK")
    private long bId;
    private String name;
    private String address;
    @JoinColumn(name = "a_id", referencedColumnName = "aId")
    @OneToOne(mappedBy = "b", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    A a;
}

public void insertAB(){
    B b = new B();
    b.setName("B-Name");
    b.setAddress("B-Address");

    A a = new A();
    a.setName("A-Name");
    a.setAddress("A-Address");
    a.setB(b);
    b.setA(a);
    aRepository.save(a);
}

我可以看到这种 table h2 table:-

答:-

B:-

对于 B table,正如我在代码中提到的那样,我期待一个列 a_id

所以如果我尝试像这样检索 B,我会在我的控制器中:-

@GetMapping(value = "/getb/{id}")
public B getB(@PathVariable long id){
   var b =  bRepository.findById(id).get();
   return b;
}

{
"name": "B-Name",
"address": "B-Address",
"a": {
    "name": "A-Name",
    "address": "A-Address",
    "b": {
        "name": "B-Name",
        "address": "B-Address",
        "a": {
            "name": "A-Name",
            "address": "A-Address",
            "b": {
                "name": "B-Name",
                "address": "B-Address",
                "a": {
                    "name": "A-Name",
                    "address": "A-Address",
...........

它就像A链和B链,其中有很多。我在学习hibernate和table的关系。显然我误解了一些东西。我的意图是双向的,当我加载 A 时,我可以访问相关的 B。当我加载 B 时,我可以访问相关的 A。我怎样才能实现这个目标?

这个解决方案并不理想,因为:

  • 这只会从 json.
  • 中删除过多的数据
  • Hibernate 将执行相同的请求,这可能会降低您的应用程序速度。
  • 在 java 实体中设置 jackson 注释 (@JsonManagedReference) 不是一个好习惯。

==> 您可能必须更改关系类型

对于双向一对一关系,这种注释对我有用:-

@Getter
@Setter
@NoArgsConstructor
@ToString
@Entity
public class A {
   @Id
   @GeneratedValue
   private long aId;
    String name;
    String address;
    @JsonManagedReference // this for parent to avoid infinite recursion
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "b_id_FK") // B table foreign key in A table
    B b;
}

@Getter
@Setter
@NoArgsConstructor
@ToString
@Entity
public class B {
    @Id
    @GeneratedValue
    @Column(name = "b_id_PK")
    private long bId;
    private String name;
    private String address;
    @NotNull
    @JsonBackReference // this for child to avoid infinite recursion
    @JoinColumn(name = "a_id_FK") // A table foreign key in B table
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private A a;
}

这样我就可以在 A 和 B 中都有外键 table。这样我就可以双向访问了。