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

Sha*_*haw 17 java sql rdbms hibernate

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

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

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

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

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

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

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

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

<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>
Run Code Online (Sandbox Code Playgroud)
create table Person (personId bigint not null primary key)
create table Address (addressId bigint not null primary key, personId bigint not null)
Run Code Online (Sandbox Code Playgroud)

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

APC*_*APC 14

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

这有两个方面:

  • 单向
  • 一个一对多

线程 @CalmStorm的答案被删除的链接地址只有这些东西的第二位,但让我们开始吧.

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

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

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

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

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

  • 我不确定你是否推荐单向一对多或不一对一 (7认同)