在Hibernate联机文档中,在7.2.3节“一对多”下提到:
外键上的单向一对多关联是一种不常见的情况,因此不建议这样做。您应该使用联接表进行这种关联。
我想知道为什么?我唯一想到的是,它可能会在级联删除期间产生问题。例如,“人”是指外键上一对多关系上的地址,并且该地址将拒绝在该人之前被删除。
任何人都可以解释该建议背后的合理性吗?
这是参考文档内容的链接: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> create table Person (personId bigint not null primary key) create table Address (addressId bigint not null primary key, personId bigint not null) 您应该使用联接表进行这种关联。
外键上的单向一对多关联是一种不常见的情况,因此不建议这样做。
<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)
您应该使用联接表进行这种关联。
这有两个方面:
该线程 @CalmStorm 的答案被删除的链接地址只有这些东西的第二位,但让我们开始吧。
该线程建议用联接表替换一对多关系,因为否则,一对多方法“用不属于该实体的列填充许多副表,仅用于“链接” porpuses(原文如此) ‘。这种策略可能会在Hibernate层中产生干净的模型,但不幸的是,这会导致数据库损坏。
因为SQL只能断言子记录有一个父记录;没有办法强制父母必须有孩子的规则。因此,没有办法坚持要求表在联接表中具有条目,结果是有可能具有孤立的子记录,这正是外键旨在防止的。
我还有其他一些反对意见,但下一个最重要的反对意见是不适当。相交表旨在表示多对多关系。用它们表示一对多的关系会造成混乱,并且我喜欢过多的其他数据库对象。
因此,第二个方面是: 单向 一对多关联。这些问题是Hibernate默认情况下处理它们的特殊方式。如果我们在同一事务中插入一个父项和一个子项,则Hibernate插入子项记录,然后插入父项,然后使用父项的键更新子项。这需要可延期的外键约束(yuck!),也可能需要不可延期的非null约束(double yuck)。
有两个解决方法。一种是使用双向的一对多关联。根据文档中的引用,这是最常见的方法。另一种方法是调整子对象的映射,但这有其自身的影响。