为什么 Hibernate 文档建议使用连接表来实现一对多关系?

发布于 2024-11-23 15:42:21 字数 617 浏览 1 评论 0原文

我认为在数据库中建模一对多关系的常用方法是通过外键关系(即一个拥有多个订单的客户 -> 订单表获取对客户表的 FK 引用)。

但是,Hibernate 建议使用连接表来建模此类关系:

使用拥有的外键列进行单向一对多 实体并不常见,也不真正推荐。我们强烈 建议您对这种关联使用连接表(如 下一节将解释)。描述了这种关联 通过@JoinColumn。

http://docs.jboss .org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

为什么“不真正推荐”。我认为使用 FK 是标准,并且联接表仅用于多对多关系?

我不喜欢创建连接表,因为数据模型看起来像是多对多的关系,而实际上它是一对多的。

Hibernate 文档中提出此建议的原因是什么?

I thought that the common way to model a one-to-many relation in a database is via a foreign key relationship (i.e. one customer with many orders -> order table gets a FK reference to customer table).

However, Hibernate recommends to use a join table to model such relationships:

A unidirectional one to many using a foreign key column in the owned
entity is not that common and not really recommended. We strongly
advise you to use a join table for this kind of association (as
explained in the next section). This kind of association is described
through a @JoinColumn.

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

Why is this "not really recommended". I thought the using an FK was the standard, and that join tables are only used for many-to-many relationships?

I don't like to create a join table, because the data model will look like the relationship is many-to-many, when in fact it is one-to-many.

What is the reason for this recommendation in the Hibernate docs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最丧也最甜 2024-11-30 15:42:21

这个问题已在 Hibernate 论坛上提出并回答:https://forum.hibernate.org/viewtopic.php?t=954178&highlight=uni Direction+null+foreign+foreign+key。这似乎不是数据库设计的问题,而是 Hibernate 如何运行的问题。

This question has been asked and answered on the Hibernate forums: https://forum.hibernate.org/viewtopic.php?t=954178&highlight=unidirectional+null+foriegn+foreign+key. It appears to be less an issue fo DB design and more one of how Hibernate functions.

别再吹冷风 2024-11-30 15:42:21

您发布的文档中的引文描述了单向 @OneToMany 关联,这是不同的事情。在这样的关联中,您只有从客户到订单的引用,而不是相反。因此,应该使用连接表来映射这种关联,该表保存每个客户的订单集合。

我想您正在考虑的关联更可能是 @ManyToOne 关联,具有从订单到客户的引用。

请注意,如果要对双向关联进行建模,可以在 @OneToMany 注释中使用“mappedBy”属性。

The citation from the documentation you have postet describes a unidirectional @OneToMany association, which is a different thing. In such an association, you only have a reference from Customer to Orders, not vice verca. So mapping that kind of association should be done with a join table, holding the collection of Orders for each Customer.

I guess the association you are thinking of is more likely a @ManyToOne association, with having the reference from Order to Customer.

Note that if you want to model a bidirectional association, you can use the "mappedBy" attribute in the @OneToMany annotation.

眉目亦如画i 2024-11-30 15:42:21

我无法与任何权威人士交谈,但我的看法始终是,对于单向关系,您的订单更有可能成为多个此类关系的接收端。这也会增加订单在其中某些列中出现空值的可能性,因为订单已创建,但可以引用订单的其他对象要么尚不存在,要么永远不会存在。就这一点而言,将 FK 列移至另一个表是一个标准化问题。还有一个事实是它更好地反映了对象关系。在来自 Foo 的单向一对一中 -> Bar,您希望在 Foo 中找到 FK,而不是在 Bar 中,因为那是对象模型中所有权所在的位置。这同样适用于来自 Customer -> 的单一一对多。命令。查看对象模型,您不希望看到订单中表示的所有权,因此也不希望在订单表中看到所有权。

I can't speak with any authority, but my take on it has always been that with unidirectional relationships, there's a higher probability that your Order will be at the receiving end of multiple such relationships. That also increases the probability that the Order will have nulls in some of those columns because the Order has been created, but other objects that can reference the Order either don't exist yet or never will. On that count, it's a question of normalization to move the FK columns out to another table. Then there's also the fact that it better mirrors the object relationships. In a unidirectional one-to-one from Foo -> Bar, you'd expect to find the FK in Foo, not in Bar, because that's where the ownership is in the object model. The same applies to a uni-one-to-many from Customer -> Order. Looking at the object model, you don't expect to see ownership represented in the Order, hence not in the Order table either.

彼岸花似海 2024-11-30 15:42:21

Hibernate 文档的上一节介绍了双向一对多关系,并描述了您可能习惯的内容,以及多个实体上的标准外键。正如其他人所说,只有当您明确想要单向关系时,这个答案才合适。

如果多方不知道这种关系,您只需要单向性。这意味着多方的类不能有属性来表示关系,几乎按照定义。因此,可以将此问题视为“在不使用正常方法的情况下如何表示一对多关系”。

想要这样的单向关系当然有些不寻常,但我可以看到您出于解耦、安全、审计或不变性原因可能需要它的情况。例如,假设您正在对一项临床试验进行建模,您的类别是患者和药物,并且在试验期间您为每位患者提供一组药物中的一种。您希望对患者进行操作的任何逻辑都与分配给他们的药物完全解耦。因此,您不必像平常那样使用 Patient.setMedicate(),而是创建连接类 MeminationPatientMap 并调用 Medicine.getMeductionPatientMap().addPatient(Patient)。然后,您可以通过药物方面的逻辑来控制对药物的访问与患者的一对多关系。

我不认为“客户订单”是一个很好的例子,因为通常我们的订单心智模型期望可以通过它联系到客户。事实上,大多数时候你不是

The previous section in the Hibernate docs covers Bidirectional One-to-many relationships and describes what you are probably used to, with a standard foreign key on the many entity. As others have said, this answer is only appropriate when you explicitly want a unidirectional relationship.

You would only want unidirectionality if the many side must not be aware of the relationship. That means the class on the many side can't have an attribute to represent the relationship, almost by definition. So think of this problem as asking "how do I represent a one-to-many relationship without using the normal approach".

Wanting a unidirectional relationship like this certainly is somewhat unusual, but I can see situations where you might want it for decoupling, security, auditing, or immutability reasons. For example, lets say that you are modeling a clinical trial, and your classes are Patient and Medication, and during the trial you give one of a set of medications to each patient. You want any logic that operates on Patient to be completely decoupled to which Medication is allocated to them. So instead of using patient.setMedication() as you normally would, you create the join class MedicationPatientMap and call medication.getMedicationPatientMap().addPatient(patient). Then you can control access to the medication to patient one-to-many relationship with logic on the medication side.

I don't think Customer-Order is a good example of this, because normally our mental model of orders expect Customers to be reachable from it. And really, most of the time you aren't

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文