【问题标题】:JPA and how to think about relationshipsJPA 以及如何思考关系
【发布时间】:2016-06-28 11:42:26
【问题描述】:

我正在学习 JPA 关系(@OneToOne、@ManyToOne、...),当我与人们谈论他们如何为实体建模时,我越来越困惑。这是昨天的一个例子:

假设我们在PersonAddress 之间建立了关系。 DB 将Address.id 作为FK 存储在Persons 表中作为“address_id”。这种关系是 OneToOne 还是 OneToMany?我听说人们为这两种观点争论不休,他们都有充分的理由说明他们为什么会有这种感觉。

有人认为它“是一个多对一,因为每条记录的 address_id 不是唯一的。相同的 address_id 可以在Persons 表中反复使用。他认为,要真正拥有 OneToOne, Persons 表中的 FK 必须按照 JSR 规范中的指示是唯一的。

另一个人说,“当你想到一个Person 记录时,他们会有多个Address 吗?如果没有,那就是OneToOne;为什么要把事情复杂化”

我不知道哪个是真的。一方面,第一个人能够提出 JSR 规范并与我交谈。另一方面,我有一位拥有 20 多年经验(并且备受尊敬)的开发人员告诉我要保持简单。

有人可以帮我澄清一下吗

谢谢!

【问题讨论】:

    标签: java hibernate jpa orm


    【解决方案1】:

    我将讨论从 Person 到 Address 的关联。

    一个给定的人不能有多个地址,因为它的关联表有一个指向地址的外键列。

    所以,它可以是 OneToOne 或 ManyToOne。

    由您决定它是哪一个,并且选择不取决于任何技术。如果您不希望两个不同的人共享同一个地址,那么它就是 OneToOne。如果您决定两个人可以共享同一个地址,那么它就是 ManyToOne。

    如果是 OneToOne,你应该确保它确实是 OneToOne,并且两个人不能共享同一个地址。最有效和最简单的方法是添加 person 表的 address_id 列的唯一约束。但是 Hibernate 并不关心你是否设置了那个约束。

    您的“其他人”是错误的。如果两个人可以共享同一个地址,那么它应该是一个多对一。不是一对一。想象一下,您将其设为双向关联:由于地址可以由多个人共享,因此您将在 Address 和 Person 之间建立 OneToMany 关联,这将与 Person 和 Address 之间的关联相反。并且 OneToMany 的反向关联必须是 ManyToOne,而不是 OneToOne。

    【讨论】:

      【解决方案2】:

      我们有 Person 和 Address 。我们需要确定它们之间的关系。 您可以通过以下两种不同方式查看关系

      1. 从个人到地址
      2. 从地址到人

      1.从人到地址

      从您的表格中获取一个地址实例或行,然后问问自己这个特定的地址行是否与多个人有关系。 如果是,则如果没有人的一侧是一,则人的一侧是多的。 所以在这个阶段你已经确定了人是多还是一

      现在从您的表中选择一个人实例或行,并问自己这个特定的人是否有多个地址。如果是,则关系的地址端是许多其他地址端是一个。

      你的例子

      Person 有一个引用地址 id 的外键

      根据这些信息让我们进行头脑风暴

      一个人可以有多个相关地址吗??? person 表中的每个人都有一个引用地址行的外键(address_id)。鉴于 address_id 不是多值的,我们可以说一个人只能有一个与之相关的地址。 所以关系的地址端是 ONE

      一个地址可以属于多个人吗?

      据我们所知,person 有 address_id,它是 Address 的外键。并且没有指定 address_id 是唯一的约束。即 address_id 列对于 Person 表上的多行可以具有相同的值。因此我们可以说多个人可以具有相同的地址。 所以关系的人方面是很多

      最后我们得出结论 PERSON-TO-ADDRESS 的关系是多对一的

      注意:- 如果 person 表中的外键 address_id 应用了唯一约束,在这种情况下,多个人将无法引用同一个地址,从而使关系的 Person 侧为 ONE。因此,这种关系将变成一对一

      【讨论】:

        【解决方案3】:

        某些数据库没有直接选项来设置一对一关系。您可以使用 @JB Nizet 所说的唯一约束或使用 Person.id 作为 Adress 表的主键以及 Person 表的外键来强制它。

        如果您不这样做,在不知道您正在使用的数据值的情况下,您将无法确保关系是 1:1 或 1:n。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-25
          • 2013-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-18
          相关资源
          最近更新 更多