我目前有一个关系,父实体知道它的孩子是这样的:
@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。
进行上述更改时,我的现有数据会发生什么变化?如果可能,我们不想搞乱现有数据。
答案 0 :(得分:0)
会发生什么? 它们适用于不同的概念。
“mappedBy”用于相互关联双向关系的两端。
指定为1-N的 @JoinColumn
简单地说“将关系存储在另一方的FK中”。这并不意味着这种关系是双向的或单向的,也可能是。
建议使用@JoinColumn
,因此您要清楚它是通过相关对象中的FK。
答案 1 :(得分:0)
要创建双向@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 );
}
答案 2 :(得分:0)
我设法保持了从父母到孩子的现有关系。
为此,我直接在数据库中查找了外键列的名称,在本例中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;
}