可能重复:
Hibernate unidirectional one to many association - why is a join table better?
在Hibernate在线文档中,在7.2.3一对多部分中,提到了:
单向一对多关联 在外键上是一个不寻常的案例, 并不推荐。你应该 而是使用这种连接表 协会。
我想知道为什么?我唯一想到的是,它可以在级联删除期间产生问题。例如,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 :(得分:14)
单向一对多关联 在外键上是一个不寻常的案例, 并且不推荐。
这有两个方面:
thread @CalmStorm 删除的答案仅链接到地址中的第二个,但让我们从它开始。
该线程建议用连接表替换一对多关系,因为否则一对多方法'使用不属于该实体的列填充多个边表,仅用于“链接”porpuses (原文如此)”。这种策略可能会在Hibernate层中产生一个干净的模型,但不幸的是它会导致数据库损坏。
因为SQL只能声明子记录有父记录;没有办法强制执行父母必须有孩子的规则。因此,没有办法坚持表中的连接表中有条目,结果是有可能有孤立的子记录,这是外键要防止的。
我还有其他几个异议,但下一个最重要的是不恰当。交叉表旨在表示多对多关系。使用它们来表示一对多关系会让人感到困惑,并且需要太多额外的数据库对象。
所以,第二个方面:单向一对多关联。这些问题是Hibernate默认处理它们的特殊方式。如果我们在同一个事务中插入父项和子项,Hibernate会插入子记录,然后插入父项,然后使用父项的键更新子项。这需要可延迟的外键约束(哎呀!),也可能是可延迟的非空约束(双重约束)。
这有几种解决方法。一种是使用双向一对多关联。根据{{3}},这是最常见的方法。另一种方法是调整子对象的映射,但这有其自身的分支。