2010-01-19 91 views
17

可能重复:
Hibernate unidirectional one to many association - why is a join table better?为什么建议避免外键上的单向一对多关联?

在Hibernate的在线文档,根据第7.2.3 1对许多人来说,它提到,认为:

一个单向对外关键字 是一种不寻常的情况, 并且不推荐。您应该使用 而不是使用此关联的此类 的连接表。

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

任何人都可以解释推荐背后的理由吗?

这里是链接到参考文档内容:7.2.3. One-to-many

我复制粘贴在这里的实际内容:

单向的一对多关联的外键是一个 异常情况,并不建议。

<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) 

你应该使用一个连接表对于这种关联的。基于外键

+0

请参阅http://stackoverflow.com/questions/1307203/hibernate-unidirectional-one-to-many-association-why-is-a-join-table-better – 2012-10-23 11:24:13

回答

14

单向一个一对多的关联 是一个不寻常的情况下, ,不推荐。

有两个方面是:

  • 单向
  • 一个一对多

thread@CalmStorm的答案被删除的链接地址仅第二这些东西,但让我们先从它开始。

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

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

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

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

这有几个解决方法。一种是使用双向一对多关联。根据in the document you cite这是最常见的方法。另一种方法是调整子对象的映射,但它有其自身的影响。

+0

谢谢,这说明了很多! – Shaw 2010-01-20 04:28:30

+7

我不确定您是否推荐单向一对多或者不是 – 2011-02-01 13:28:13

+1

我同意@Pangea。 APC提出了一些很好的观点,其中一些我同意,但不清楚APC认为什么是一个好的解决方案。 – 2012-06-29 14:33:51

相关问题