我目前有一个关系,其中父实体知道其子实体,如下所示:
@Entity
public class Parent{
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn
private Set<Child> children = new HashSet<>();
}
@Entity
public class Child{
// no link to parent
}
现在我想让它成为这样的双向关系:
@Entity
public class Parent{
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
private Set<Child> children = new HashSet<>();
}
@Entity
public class Child{
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
}
底层数据库是 OracleDB。
执行上述更改时,我的现有数据会发生什么情况?如果可能的话,我们不想弄乱现有数据。
要创建双向@OneToMany使用mappedBy是正确的。它设置关系的所有者。在数据库中外键在子实体上设置。
每当形成双向关联时,应用程序开发人员必须确保双方始终保持同步。在 Parent
类中,创建如下addChild
和removeChild
方法:
public void addChild(Child child) {
children.add( child );
child.setParent( this );
}
public void removeChild(Child child) {
children.remove( child);
child.setParent( null );
}
会发生什么?它们用于不同的概念。
"mappedBy">用于将双向关系的两端相互关联。
@JoinColumn
指定为1-N 只是说"将关系存储在另一侧的 FK 中"。这并不意味着这种关系是双向的或单向的,也可能是
。建议使用该@JoinColumn
,因此请明确表示它是通过相关对象中的 FK 进行的。
我设法保持了从父母到孩子的现有关系。
为此,我直接在数据库中查找外键的列名称,在本例中CHILD_ID
表中CHILD
。此列包含父级(自动生成(的 ID。
现在我只是简单地将这个名称硬编码到 JPA 中。现在这是一个奇怪的命名,但没有数据丢失。
这是最终代码:
@Entity
public class Parent{
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
private Set<Child> children = new HashSet<>();
}
@Entity
public class Child{
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CHILD_ID") // <- for data migration
private Parent parent;
}