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

发布于 2024-08-18 04:34:37 字数 1258 浏览 1 评论 0原文

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

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

单向一对多关联 在外键上是一种不寻常的情况, 并且不推荐。你应该 而是使用这种连接表 协会。

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

谁能解释一下建议背后的理由?

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

我已将实际内容复制粘贴到此处:

外键上的单向一对多关联是 特殊情况,不推荐使用。

<类名=“人”>
    
        <生成器类=“native”/>
    
    <设置名称=“地址”>
        <键列=“personId” 
            not-null="true"/>
        <一对多类=“地址”/>
    


<类名=“地址”>
    
        <生成器类=“native”/>
    

<小时>
创建表Person(personId bigint不为空主键)
创建表Address(addressId bigint not null主键,personId bigint not null)

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

Possible Duplicate:
Hibernate unidirectional one to many association - why is a join table better?

In the Hibernate online documentation, under section 7.2.3 One-to-many, it's mentioned, that:

unidirectional one-to-many association
on a foreign key is an unusual case,
and is not recommended. You should
instead use a join table for this kind
of association.

I would like to know why? The only thing that comes to my mind is, it can create problems during cascade deletes. For example, Person refers to address on a one to many relationship on a foreign key, and the address would refuse to be deleted before the person.

Can anyone explain the rational behind the recommendation?

Here is the link to the reference document content: 7.2.3. One-to-many

I have copy pasted the actual content here:

A unidirectional one-to-many association on a foreign key is an
unusual case, and is not recommended.

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

You should instead use a join table for this kind of association.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红尘作伴 2024-08-25 04:34:37

单向一对多关联
在外键上是一种不寻常的情况,
并且不推荐。

这有两个方面:

  • 单向
  • 一对多

线程 @CalmStorm删除的答案链接仅解决了其中的第二个问题,但让我们从它开始。

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

因为SQL只能断言子记录有父记录;没有办法强制执行父母必须有孩子的规则。因此,无法坚持表在连接表中包含条目,结果是可能会出现孤立的子记录,而这正是外键旨在防止的情况。

我还有其他几个反对意见,但下一个最重要的反对意见是不恰当。交集表旨在表示多对多关系。使用它们来表示一对多关系很令人困惑,并且根据我的喜好需要太多额外的数据库对象。

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

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

unidirectional one-to-many association
on a foreign key is an unusual case,
and is not recommended.

There are two aspects to this:

  • unidirectional
  • one-to-many

The thread @CalmStorm's deleted answer links to addresses only the second of these things, but let's start with it.

That thread recommends replacing one-to-many relationships with join tables because otherwise the one-to-many approach 'populates the many side table with columns that don't belong to that entity, are there only for "linking" porpuses (sic)'. This tactic may result in a clean model in the Hibernate layer but unfortunately it results in a broken database.

Because SQL can only assert that the child record has a parent; there is no way to enforce a rule that the parent must have a child. Consequently there is no way to insist that a table have entries in a join table, the upshot being that it becomes possible to have orphaned child records, the very thing that foreign keys are intended to prevent.

I have several other objections, but the next most important one is inappropriateness. Intersection tables are meant to represent many-to-many relationships. Using them to represent one-to-many relationships is confusing and requires too many additional database objects for my liking.

So, to the second aspect: unidirectional one-to-many associations. The problem with these is the peculiar fashion in which Hibernate handles them by default. If we insert a parent and a child in the same transaction, Hibernate inserts the child record, then it inserts the parent, then it updates the child with the parent's key. This requires deferrable foreign key constraints (yuck!) and probably deferrable not null constraints as well (double yuck).

There are a couple of workarounds to this. One is to use birectional one-to-many associations. According to in the document you cite this is the most common approach. The other approach is to tweak the mapping of the child object but that has its own ramifications.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文