java 为什么建议避免外键上的单向一对多关联?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2092611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is it recommended to avoid unidirectional one-to-many association on a foreign key?
提问by Shaw
Possible Duplicate:
Hibernate unidirectional one to many association - why is a join table better?
In the Hibernate online documentation, under section 7.2.3 One-to-many, it's mentioned, that:
在 Hibernate 在线文档的 7.2.3 一对多部分下,提到:
unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended. You should instead use a join table for this kind of association.
外键上的单向一对多关联是一种不常见的情况,不推荐使用。您应该为这种关联使用连接表。
I would like to know why? The only thing that comes to my mind is, it can create problems during cascade deletes. For example, Person refers to address on a one to many relationship on a foreign key, and the address would refuse to be deleted before the person.
我想知道为什么?我唯一想到的是,它会在级联删除期间产生问题。例如,Person 是指外键上一对多关系上的地址,地址会在人之前拒绝删除。
Can anyone explain the rational behind the recommendation?
任何人都可以解释建议背后的合理性吗?
Here is the link to the reference document content: 7.2.3. One-to-many
这是参考文档内容的链接:7.2.3。一对多
I have copy pasted the actual content here:
我已将实际内容复制粘贴到此处:
A unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended.
<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses"> <key column="personId" not-null="true"/> <one-to-many class="Address"/> </set> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> </class>create table Person (personId bigint not null primary key) create table Address (addressId bigint not null primary key, personId bigint not null)You should instead use a join table for this kind of association.
外键上的单向一对多关联是一种不常见的情况,不推荐使用。
<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses"> <key column="personId" not-null="true"/> <one-to-many class="Address"/> </set> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> </class>create table Person (personId bigint not null primary key) create table Address (addressId bigint not null primary key, personId bigint not null)您应该为这种关联使用连接表。
采纳答案by APC
unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended.
外键上的单向一对多关联是一种不常见的情况,不推荐使用。
There are two aspects to this:
这有两个方面:
- unidirectional
- one-to-many
- 单向
- 一对多
The thread@CalmStorm's deleted answer links to addresses only the second of these things, but let's start with it.
该线程@CalmStorm的答案被删除的链接地址只有这些东西的第二位,但让我们开始吧。
That thread recommends replacing one-to-many relationships with join tables because otherwise the one-to-many approach 'populates the many side table with columns that don't belong to that entity, are there only for "linking" porpuses (sic)'. This tactic may result in a clean model in the Hibernate layer but unfortunately it results in a broken database.
该线程建议用连接表替换一对多关系,因为否则一对多方法会用不属于该实体的列填充多边表,是否仅用于“链接”porpuses(原文如此) '。这种策略可能会导致 Hibernate 层中的模型干净,但不幸的是它会导致数据库损坏。
Because SQL can only assert that the child record has a parent; there is no way to enforce a rule that the parent must have a child. Consequently there is no way to insist that a table have entries in a join table, the upshot being that it becomes possible to have orphaned child records, the very thing that foreign keys are intended to prevent.
因为SQL只能断言子记录有父记录;没有办法强制执行父母必须有孩子的规则。因此,没有办法坚持一个表在连接表中有条目,结果是可能有孤立的子记录,外键旨在防止这种情况。
I have several other objections, but the next most important one is inappropriateness. Intersection tables are meant to represent many-to-many relationships. Using them to represent one-to-many relationships is confusing and requires too many additional database objects for my liking.
我还有其他几个反对意见,但下一个最重要的反对意见是不当。交集表旨在表示多对多关系。使用它们来表示一对多关系令人困惑,并且需要太多额外的数据库对象来满足我的喜好。
So, to the second aspect: unidirectionalone-to-many associations. The problem with these is the peculiar fashion in which Hibernate handles them by default. If we insert a parent and a child in the same transaction, Hibernate inserts the child record, then it inserts the parent, then it updates the child with the parent's key. This requires deferrable foreign key constraints (yuck!) and probably deferrable not null constraints as well (double yuck).
那么,到第二个方面:单向一对多关联。这些的问题在于 Hibernate 默认处理它们的特殊方式。如果我们在同一个事务中插入一个父级和一个子级,Hibernate 插入子记录,然后插入父级,然后用父级的键更新子级。这需要可延迟的外键约束(糟糕!),并且可能还需要可延迟的非空约束(双重糟糕)。
There are a couple of workarounds to this. One is to use birectional one-to-many associations. According to in the document you citethis is the most common approach. The other approach is to tweak the mapping of the child object but that has its own ramifications.
对此有几种解决方法。一种是使用双向一对多关联。根据您引用的文档,这是最常见的方法。另一种方法是调整子对象的映射,但这有其自身的影响。

