JPA @OneToMany -> 父项 - 子引用(外键)

2022-09-01 00:39:49

我有一个关于引用来自儿童Entites ir的Parententities的问题,如果我有这样的东西:

家长.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 ...
}

孩子.java:

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

    @ManyToOne
    private Parent parent;

    ... simple getter an setter
}

将创建下表:

Parent:
     int id

Child:
     int id
     int parent_id (foreign key: parent.id)

好吧,到目前为止,一切都很好。但是当涉及到使用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);
}

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

Parent:
     id
     100

Child
     id     paren_id
     101    100

但事实并非如此,你必须明确地将父母设置为孩子(我认为,框架本身可能可以做到这一点)。

所以数据库中真正的东西是这样的:

Parent:
     id
     100

Child
     id     paren_id
     101    (null)

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

我真的必须做sth吗?喜欢这个?

家长.java:

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

    this.children = children;
}
...

编辑:

根据快速回复,我能够通过使用引用拥有实体上的@JoinColumn来解决此问题。如果我们从上面取例子,我做了sth。喜欢这个:

家长.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 ...
}

孩子.java:

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

    ... simple getter an setter
}

现在,如果我们这样做:

@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);
}

引用由父项正确设置:

Parent:
     id
     100

Child
     id     paren_id
     101    100

答案 1

我真的必须做sth吗?喜欢这个?

是的,这是一种策略。

在双向关系中,这种关系有“拥有”和“非拥有”的一面。因为在你的案例中,拥有方是开着的,所以你需要在那里设置关系,让它持久化。所属方通常由您指定的位置确定,但看起来您使用的不是该批注,因此很可能是从您在批注中使用的事实推断出来的。Child@JoinColumnmappedByParent

您可以在此处阅读有关此内容的更多信息


答案 2

情况似乎仍然如此。在父母中,你可以有这样的东西Entity

@PrePersist
private void prePersist() {
   children.forEach( c -> c.setParent(this));
}

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


推荐