【问题标题】:JPA one to one mappingJPA 一对一映射
【发布时间】:2015-07-28 13:26:55
【问题描述】:

我有以下具有一对一映射的表结构。

public class Parent {
 private long parentPK(Parent primary key); 
 private Child child;

    @OneToOne(
        cascade = {CascadeType.ALL },
        fetch = FetchType.LAZY,
        mappedBy = "child"
    )
    public Child getChild() {
        return this.child;
    } 
}

public class Child{

private long childPK(Child primary key); 
private Parent parentFK;(parent foreign key)

   @OneToOne
    @JoinColumn(
        name = "PARENT_FK",
        referencedColumnName = "PARENT_PK"
    )
    public Parent getParentFK() {
        return this.parentFK;
    }
}

注意:父表没有对子表的引用。 Child 将父主键作为外键列。这里父母和孩子的主键是不同的。

根据我的要求,在持久化父级时,子记录应自动持久化,而无需显式设置子表的外键。 使用上述结构执行导致“无法在 CHILD 表中插入 PARENT_FK 的非空记录”。 有人可以指导实现上述要求的可能性吗?

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    你的映射不正确。

    您在这里遇到的主要问题是您的 mappedBy = “child” 指的是 Child 类的子属性,而不是 Parent 类。子类没有子属性,您需要引用Child 类的parentPK 属性。

    我建议不要在实体字段名称中使用 PK/FK,因为这可能会有点混乱。

    以下是更新后的父/子实体。 (我已切换到字段访问,但这只是我的偏好)

    @Entity
    public class Child  {
        @Id
        @Column(name = "childPK")
        private Long id;
    
        @OneToOne
        @JoinColumn(
            name = "PARENT_FK",
            referencedColumnName = "PARENT_PK"
        )
            private Parent parent;
    
    @Entity
    public class Parent {
    
        @Id 
        @Column(name = "PARENT_PK")
        private long id;
    
            @OneToOne(
            cascade = {CascadeType.ALL},
            fetch = FetchType.LAZY,
     -->    mappedBy = "parent")  //Refers to parent field of the Child class
    
            private Child child;
    

    请注意,您已经定义了双向 OneToOne 关系。在 JPA 中,双向关系有一个拥有方 - 具有连接信息的一方,在你的情况下为 Child - 和一个相反的一方 - 具有 mappedBy 属性的一方,Parent 在你的情况下案子。掌握这一点是个好主意。此参考资料着眼于 OneToOne 关系,并且还有很多其他的关系。 https://en.wikibooks.org/wiki/Java_Persistence/OneToOne

    【讨论】:

      【解决方案2】:

      您的映射是正确的,并且您没有提供保存操作的保存代码。

      但是如果不提供对父级的引用,您就无法保存子级,您不必设置外键,但在您的保存方法中,您应该同时执行以下两项操作:

      parent.setChild(child);
      child.setParent(parent);
      

      【讨论】:

        【解决方案3】:

        我确实遇到过类似的情况。您的映射和一切看起来都不错。看起来您已经设置了 Child 的 Parent 实体,而没有将 Parent 设置为此 Child 实体。那是您试图在不设置其父级的情况下保存子级。因此,您可能需要执行以下操作:

        Parent p= new Parent();
        Child c = new Child();
        p.setChild(c);
        // c.setParent(p);    Looks like this is missing in your code
        session.save();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-02
          • 2020-01-06
          • 1970-01-01
          • 2021-09-15
          • 1970-01-01
          相关资源
          最近更新 更多