为什么建议避免外键上的单向一对多关联?

可能重复:
Hibernate单向一对多关联 – 为什么连接表更好?

在Hibernate在线文档中,在第7.2.3节“一对多”中,提到了:

外键上的单向一对多关联是一种不常见的情况,不建议这样做。 您应该使用连接表进行此类关联。

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

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

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

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

外键上的单向一对多关联是一种不常见的情况,不建议这样做。

              

 create table Person (personId bigint not null primary key) create table Address (addressId bigint not null primary key, personId bigint not null) 

您应该使用连接表进行此类关联。

外键上的单向一对多关联是一种不常见的情况,不建议这样做。

这有两个方面:

  • 单向
  • 一个一对多

线程 @CalmStorm删除的答案只链接到地址中的第二个,但让我们从它开始。

该线程建议用连接表替换一对多关系,因为否则一对多方法’用不属于该实体的列填充许多边表,只有“链接”porpuses(sic) ”。 这种策略可能会在Hibernate层中产生一个干净的模型,但不幸的是它会导致数据库损坏。

因为SQL只能声明子记录具有父记录; 没有办法强制执行父母必须有孩子的规则。 因此,没有办法坚持表中的表有连接表中的条目,结果是可能有孤立的子记录,外键是要防止的。

我还有其他几个异议,但下一个最重要的是不恰当。 交叉表用于表示多对多关系。 使用它们来表示一对多关系是令人困惑的,并且需要太多额外的数据库对象供我喜欢。

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

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