【问题标题】:Owning Side vs Non-Owning Side In hibernate and its usage in reference of mapped by element?拥有方与非拥有方在休眠中及其在元素映射参考中的用法?
【发布时间】:2014-01-22 22:07:51
【问题描述】:

我在学习hibernate时遇到了这些术语,即owning side and non-owningside。例如:-这里是 关于在一对一映射中使用 mappedby 元素的声明

如果关系是双向的,非拥有方必须使用 OneToOne 注释的mappedBy 元素 指定拥有方的关系字段或属性。

但我没有得到owning side and non-owning 的真正含义?

【问题讨论】:

  • 你的意思是它是做什么的,或者是mappedBy这个名字背后的原因?我在下面解释了为什么它是必要的以及为什么这样称呼它,如果您还有其他问题,请告诉我。

标签: java hibernate


【解决方案1】:

“拥有”方是其表将保存引用的实体。

如果EntityPersonEntityAddress 之间存在一对一的关系,那么,如果EntityPerson 是拥有方,那么它的表中将有类似

 ADDRESS_ID int NULL FOREIGN KEY REFERENCES Address (ID)

【讨论】:

  • 我也有同样的印象。也请看我的回答
【解决方案2】:

这是我对大学有很多学生(一对多关系)的简单示例的理解

                       corresponds to       
College(Value Object) -----------------> College (Database Table)

                       corresponds to       
Student(Value Object) -----------------> Student (Database Table having column which is
                                                  foreign key to College table . 
                                                  So This is owning side and College  is
                                                  Non-owning side )

就对象表示而言,Student 对象是拥有方,因为它将具有指向大学列的引用。因此,学生是拥有方,而大学是非拥有方。

在休眠中所有者端和非所有者端在被元素映射关系中的使用

非拥有方对象

@Entity
public class College {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int collegeId;
    @OneToMany(mappedBy="college") // here non-owning side using mapped by elment to specify
                                   // the relationship field of owning side
    private List<Student> students;
    }


Owning Side Object

@Entity
public class Student {
@ManyToOne
    private College college;
}

总之,拥有方是具有对另一方的引用的实体。在 DB 方面,它 转换为具有列的表实体,该列是其他表中列的外键,例如 大学的案例有很多学生。

注意:- 拥有侧表必须包含一个连接列,该列引用另一个表的 id。这意味着拥有侧实体应该包含@joincolumn 注释,否则它会将名称视为主键列其他表的名称。见@OneToOne unidirectional and bidirectional

【讨论】:

    【解决方案3】:

    双向关系拥有方的想法源于这样一个事实,即在关系数据库中没有像对象那样的双向关系。

    在数据库中,我们只有外键,其中只有一个表可以有另一个表的外键。让我们举一个不能按预期工作的例子,看看为什么需要 mappedBy:

    @Entity
    @Table(name="PERSONS")
    public class Person {
        @OneToMany
        private List<IdDocument>  idDocuments;
    }
    
    @Entity
    @Table(name="IDDOCUMENT")
    public class IdDocument {
        @ManyToOne
        private Person person;
    }
    

    这不仅会创建表 PERSONS 和 IDDOCUMENTS,还会创建第三个表 PERSONS_IDDOCUMENTS:

    CREATE TABLE persons_iddocument
    (
      persons_id bigint NOT NULL,
      iddocuments_id bigint NOT NULL,
      CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
      CONSTRAINT fk_docs FOREIGN KEY (iddocuments_id) REFERENCES iddocument (id),
      CONSTRAINT pk UNIQUE (iddocuments_id)
    )
    

    仅注意文档上的主键。在这种情况下,Hibernate 独立跟踪关系的双方:如果您将文档添加到关系 Person.idDocuments,它会在 PERSON_IDDOCUMENTS 中插入一条记录。

    如果我们更改 IdDocument 的 Person,它会更改表 IDDOCUMENTS 上的外键 person_id。

    Hibernate 是在数据库上创建两个单向(外键)关系,来实现一个双向对象关系,因为数据库不支持双向关系。

    但我们想要的是对象关系仅通过表 IDDOCUMENTS 上的外键映射到 PERSON:一份文档只属于一个人。

    不需要额外的表,这将迫使我们在同一个数据库事务中同时修改 Person.idDocuments 和 IdDocument.person 以保持关系一致。

    为了解决这个问题,我们需要配置 Hibernate 以停止跟踪对关系 Person.idDocuments 的修改。 Hibernate 应该只跟踪关系 IdDocument.person 的另一端,为此我们添加 mappedBy:

    @OneToMany(mappedBy="person")
    private List<IdDocument>  idDocuments;
    

    这意味着“关系这一侧的修改已经被关系 IdDocument.person 的另一侧映射,因此无需在此处在额外的表中单独跟踪它”。

    这为我们提供了我们想要的映射,但有一个主要后果:

    • Hibernate 不再跟踪对 Person.idDocuments 集合的修改,开发人员有责任修改 IdDocument.person 以修改关联。

    【讨论】:

    • 这有意义吗,为什么 mappedBy 是必要的以及它的名字的原因?
    • 您的答案很好,但格式很差,并且似乎暗示了某些休眠概念。 所以我们添加了 mappedBy - 你提到了注释,但没有提到它在哪个表中,.. 这意味着“在关系的这一侧进行修改 - 这会混淆哪一边 仅注意文档上的主键:在哪个表中?还有其他拼写错误,但是如果您格式化答案,那将是一个很好的答案。同样,谢谢您写这篇文章。我一直在寻找很久以来一直有这样的答案。
    • 同一人在此处以更好的格式回答了相同的答案stackoverflow.com/questions/2749689/…
    猜你喜欢
    • 2023-04-02
    • 2023-04-11
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多