JPA @OneToMany - >父母 - 子女参考(外键)

Sim*_*0rn 43 spring hibernate jpa parent-child one-to-many

我有一个关于从Child Entites引用ParentEntities的问题如果我有这样的事情:

Parent.java:

@Entity(name ="Parent")
public class Parent {
    @Id
    @Generate.....
    @Column
    private int id;

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

    simple ... getter and setter ...
}
Run Code Online (Sandbox Code Playgroud)

而Child.java:

@Entity(name ="Child")
public class Child{
    @Id
    @Generate....
    @Column
    private int id;

    @ManyToOne
    private Parent parent;

    ... simple getter an setter
}
Run Code Online (Sandbox Code Playgroud)

将创建以下表:

Parent:
     int id

Child:
     int id
     int parent_id (foreign key: parent.id)
Run Code Online (Sandbox Code Playgroud)

好吧,到目前为止,everthings很好.但是当谈到从Java使用这个参考时,我想,你可以做这样的事情.

 @Transactional
 public void test() {
    Parent parent = new Parent();

    Child child = new Child();
    Set<Child> children = new HashSet<Child>();
    children.add(child);

    parent.setChildren(children);
    entityManager.persist(parent);
  }
Run Code Online (Sandbox Code Playgroud)

在数据库中导致这种情况:

Parent:
     id
     100

Child
     id     paren_id
     101    100
Run Code Online (Sandbox Code Playgroud)

但事实并非如此,你必须明确地将Parent设置为Child(我认为,框架可能会自行完成).

那么数据库中真的是这样的:

Parent:
     id
     100

Child
     id     paren_id
     101    (null)
Run Code Online (Sandbox Code Playgroud)

因为我没有将父母设置为孩子.所以我的问题:

我真的要做某事吗?像这样?

Parent.java:

...
setChildren(Set<Child> children) {
   for (Child child : children) {
     child.setParent.(this);
   }

   this.children = children;
}
...
Run Code Online (Sandbox Code Playgroud)

编辑:

根据快速回复,我能够通过在Reference-Owning Entity上使用@JoinColumn来解决这个问题.如果我们从上面拿出例子,我做了...... 像这样:

Parent.java:

  @Entity(name ="Parent")
    public class Parent {
        @Id
        @Generate.....
        @Column
        private int id;

        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        @JoinColumn(name= "paren_id")
        private Set<Child> children;

        simple ... getter and setter ...
    }
Run Code Online (Sandbox Code Playgroud)

而Child.java:

@Entity(name ="Child")
public class Child{
    @Id
    @Generate....
    @Column
    private int id;

    ... simple getter an setter
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们这样做:

 @Transactional
 public void test() {
    Parent parent = new Parent();

    Child child = new Child();
    Set<Child> children = new HashSet<Child>();
    children.add(child);

    parent.setChildren(children);
    entityManager.persist(parent);
  }
Run Code Online (Sandbox Code Playgroud)

父级正确设置了引用:

Parent:
     id
     100

Child
     id     paren_id
     101    100
Run Code Online (Sandbox Code Playgroud)

谢谢你的答案.

bee*_*jay 15

我真的要做某事吗?像这样?

这是一个策略,是的.

在双向关系中,存在关系的"拥有"和"非拥有"方面.因为您的案例中的拥有方已启用Child,您需要在那里设置关系以使其保持不变.拥有方通常是由您指定确定@JoinColumn,但它并不像你正在使用的注释,所以它可能是从您所使用的事实,推断mappedByParent注解.

你可以在这里阅读更多相关内容.


pir*_*rho 5

情况似乎仍然如此。在父母中,Entity您可以拥有类似

@PrePersist
private void prePersist() {
   children.forEach( c -> c.setParent(this));
}
Run Code Online (Sandbox Code Playgroud)

为了避免重复代码以在代码中的其他位置设置子代/父代关系。