为什么建议避免外键上的单向一对多关联? [英] Why is it recommended to avoid unidirectional one-to-many association on a foreign key?

查看:155
本文介绍了为什么建议避免外键上的单向一对多关联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能存在重复:


在Hibernate联机文档的第7.2.3节中,提到了:


在一个外键上的单向一对多关联
是一个不寻常的情况,
并且不推荐使用。您应该使用
来为这种类型的
关联使用连接表。


我想知道为什么?我唯一想到的是,它可能会在级联删除时产生问题。例如,Person指的是一个外键上的一对多关系的地址,并且该地址会拒绝在该人面前被删除。



任何人都可以解释理性建议后面?

以下是参考文件内容的链接: 7.2.3。一对多



我在这里复制了实际内容:


一个外键上的单向一对多关联是一个
的异常情况,不推荐使用。

 < class name =Person> 
< id name =idcolumn =personId>
< generator class =native/>
< / id>
< set name =addresses>
< key column =personId
not-null =true/>
<一对多等级=地址/>
< / set>
< / class>

< class name =地址>
< id name =idcolumn =addressId>
< generator class =native/>
< / id>
< / class>






  create table person(personId bigint不为null主键)
create table地址(addressId bigint不为null主键,personId bigint不为null)

您应该为这种关联使用连接表。



解决方案 div>


外键上的单向一对多关联
是一种不寻常的情况,
并且不推荐使用。


有两个方面:


  • 单向

  • 一对多



线程 @CalmStorm 这些东西,但让我们从它开始。



该线程建议代表与连接表关联一对多的关系,否则一对多的方法'用不属于该实体的列填充许多边表,只有连接porpuses(原文如此)'。这种策略可能会导致Hibernate层中的干净模型,但不幸的是,它会导致数据库破损。

由于SQL只能断言子记录具有父项,没有办法执行父母必须有孩子的规则。因此,没有办法坚持一张表在连接表中有条目,结果是可能有孤儿子记录,这是外键预防的目的。



我还有其他几个反对意见,但其次最重要的是不恰当。交叉表是为了表示多对多的关系。使用它们来表示一对多关系是令人困惑的,并且需要太多额外的数据库对象来满足我的喜好。

因此,对于第二个方面:单向一对多关联。这些问题是Hibernate在默认情况下处理它们的独特方式。如果我们在同一个事务中插入一个父项和一个子项,Hibernate将插入子项记录,然后插入父项,然后使用父项的关键字更新子项。这需要可延迟的外键约束(yuck!),并且可能可延迟的非空约束(double yuck)。


有几个解决方法可以解决这个问题。一种是使用双向一对多关联。根据中的你引用的文件这是最常用的方法。另一种方法是调整子对象的映射,但它有自己的分支。


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:

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.

Can anyone explain the rational behind the recommendation?

Here is the link to the reference document content: 7.2.3. One-to-many

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.

解决方案

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.

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.

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.

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: unidirectional one-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).

There are a couple of workarounds to this. One is to use birectional one-to-many associations. According to in the document you cite this is the most common approach. The other approach is to tweak the mapping of the child object but that has its own ramifications.

这篇关于为什么建议避免外键上的单向一对多关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆