【问题标题】:JPA: What happens when changing JoinColumn to mappedBy?JPA:将 JoinColumn 更改为 mappedBy 时会发生什么?
【发布时间】:2017-04-12 06:25:32
【问题描述】:

我目前有一个父实体知道其子实体的关系,如下所示:

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

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

【问题讨论】:

    标签: java jpa persistence


    【解决方案1】:

    要创建双向@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 );
        }
    

    【讨论】:

    • 是的,我知道区别。我想知道在 JoinColumn 和 mappedBy 之间切换时现有数据会发生什么
    【解决方案2】:

    会发生什么? 它们适用于不同的概念。

    "mappedBy" 用于将双向关系的两端相互关联。

    @JoinColumn 指定为 1-N 只是说“将关系存储在另一侧的 FK 中”。这并不意味着关系是双向的或单向的,两者都可以。

    使用@JoinColumn 是可取的,所以你要明确它是通过相关对象中的FK。

    【讨论】:

    • 那么,通过删除@JoinColumn,我的 FK(我猜它隐式存储在 Child 中)会被删除或在 mappedBy-FK 中重用吗?
    • 除非您将其删除,否则不会“删除”任何内容。离开 @JoinColumn 告诉它使用 FK(你已经拥有)。
    【解决方案3】:

    我设法保持了父母与孩子之间现有的关系。

    为此,我直接在数据库中查找了外键列的名称,在本例中为表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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-09
      • 1970-01-01
      • 2015-09-12
      • 2020-08-15
      • 1970-01-01
      • 2012-11-24
      • 2015-06-14
      • 2022-11-14
      相关资源
      最近更新 更多