JPA:将JoinColumn更改为mappedBy时会发生什么?

问题描述:

我现在有其中父实体知道它的孩子,像这样的关系:JPA:将JoinColumn更改为mappedBy时会发生什么?

@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的。

上述变化时,我现有的数据会发生什么变化?如果可能的话,我们不想搞乱现有的数据。

会发生什么? 他们是针对不同的概念。

“mappedBy”用于使双向关系的两端相互关联。

@JoinColumn指定为你有一个1-N只是说“将关系存储在另一边的FK”。这并不意味着这种关系是双向的,也可能是单向的。

建议使用@JoinColumn,以便在相关对象中明确指出它是通过FK进行的。

+0

所以通过移除@JoinColumn将我的FK(我想这是隐含存储在儿童)被删除或在的mappedBy-FK重用? – sotix

+0

除非您删除它,否则没有任何内容被“移除”。留下'@ JoinColumn'告诉它使用FK(你已经有了)。 –

要创建双向@OneToMany,使用mappedBy是正确的。它设置关系的所有者。在数据库中,外键在子实体上设置。

无论何时形成双向关联,应用程序开发人员都必须确保双方始终处于同步状态。 在你Parent类,创建addChildremoveChild方法,像这样:

public void addChild(Child child) { 
     children.add(child); 
     child.setParent(this); 
    } 

    public void removeChild(Child child) { 
     children.remove(child); 
     child.setParent(null); 
    } 
+0

是的,我知道区别。我想知道在JoinColumn和mappedBy之间切换时现有数据会发生什么 – sotix

我设法让家长对孩子的现有关系。

为此,我直接在数据库中查找了外键列的名称,在此例中为表CHILD中的CHILD_ID。此列包含父(自动生成)的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; 
}