【问题标题】:Trying to understand the importance of an owning side of a one-many relationship in ORM试图理解 ORM 中一对多关系的拥有方的重要性
【发布时间】:2012-01-24 05:05:52
【问题描述】:

尽管我的问题专门针对使用 Hibernate 的 Play 框架中描述实体关系的方式,但我确信这是一个一般概念。

当我们有一对多的关系时,我们总是被要求指定拥有方。

因此,例如,如果我们在 Person 和 PhoneNumber 之间有一对多的关系,我们会编写这样的代码。

@Entity
class Person {
    @OneToMany(mappedBy="person")
    public Set<PhoneNumber> phoneNumbers;
}

@Entity
class PhoneNumber {
    @ManyToOne
    public Person person;
}

在上面的代码中,拥有实体是 PhoneNumber。任何一方作为拥有实体的利弊是什么?

我意识到当拥有实体是PhoneNUMber时,表示的关系是ManyToOne,这不会导致连接表,而当拥有方是Person时,所描绘的关系将是OneToMany,在这种情况下,关系表将是已创建。

这是确定拥有方的主要原因,还是还有其他原因?

更新: 我刚刚意识到this thread 提供了部分答案,但我希望可能还有其他观点。

【问题讨论】:

    标签: hibernate orm playframework many-to-one


    【解决方案1】:

    要记住的重要一点是,拥有关系是在保存时实际保持关系的关系。举个例子:

        Person person = new Person();
        PhoneNumber pn = new PhoneNumber();
        pn.phone = "12345678";
        person.phoneNumbers.add(pn);
        session.save(person);
    

    如果您从数据库中重新加载实体,则该关系实际上不会保存,您将看不到任何数字。要实际添加关系,您需要在所有者端设置人员 (PhoneNumber),然后保存。

        // the relation is not saved
        Person loadedPerson = (Person)session.load(Person.class, person.id);
        System.out.println(loadedPerson.phoneNumbers.size()); // prints 0!
    
        pn.person = person;
        session.save(pn);
    
        loadedPerson = (Person)session.load(Person.class, person.id);
        System.out.println(loadedPerson.phoneNumbers.size()); // prints 1
    

    【讨论】:

      【解决方案2】:

      对于大多数 ORM 层,您都有延迟加载的概念。当您创建 Person 对象时,除非被要求,否则它不会加载电话集。有时,您希望如何查找数据也可以决定您如何存储它。

      例如,如果您想先提出人员,然后根据需要显示电话号码,那么在电话中保留人员参考就可以了。首先,您启动一​​个简单的查询来加载人员数据,然后根据(已加载的)person.id(另一个简单查询)查找电话号码

      虽然要一次性显示人员 + 电话数据,但您更喜欢有一个联接表,在该联接表中,您可以使用人员 ID 作为键,一次将基于人员表 + 人员电话联接表的数据加载到电话表中.在没有关系表的情况下进行查找会很昂贵。

      但坦率地说,如果您认为 SQL 而不是 ORM,那么您每次都会使用关系表:D

      【讨论】:

      • 我正在努力思考。假设在这两种情况下,我们都进行了一次急切的获取。对于第一种情况,其中 PhoneNumber 是拥有实体,我们将触发第一个查询以获取所有 Person 实体,然后为每个 Person 触发单独的查询以获取该 Person 的所有 PhoneNumber。但是,如果我们将 Person 作为拥有方,我们只需要触发一个带有连接的查询。如果这是一个愚蠢的问题,我很抱歉,但是如果 Person 是 PhoneNumber 中的 FK,则无法加入?
      • 是的,电话表中的人员 ID FK 也应该可以加入。在这里,我(假设)标准化查找会更快,但您必须查看您的解释计划才能确定。使用关系表的另一个原因(至少理论上)是允许共享电话号码,例如两个人轮班使用的电话号码。坦率地说,ORM 层的工作方式对于这些考虑应该无关紧要,因为没有人在设计架构时会考虑 ORM 层
      • 请参阅我在此线程中的答案以及名称“mappedBy”和“拥有方”的原因,如果我们不定义拥有方会发生什么,GOTCHA - stackoverflow.com/questions/2749689/…
      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2011-06-27
      • 1970-01-01
      • 2012-09-25
      • 1970-01-01
      • 2013-09-15
      • 2017-05-02
      • 2011-07-12
      相关资源
      最近更新 更多