如何在休眠状态下的多对一映射上定义反向级联删除

2022-09-02 20:46:27

我有两个A类和B类。许多B可以与单个A相关联,因此从B到A的多对一关系。我已经映射了关系,如下所示:

<class name="A" table="tbl_A">
  <property name="propA" column="colA"/>
</class>
<class name="B" table="tbl_B">
  <property name="propB" column="colB"/>
  <many-to-one name="a" class="A" column="col1" cascade="delete"/>
</class>

A 没有映射到 B 的内容。请记住,我们打算在 B 关联 A 被删除时将其删除。如果我能在 B 中的多对一关联上定义一个 inverse=“true”,但这是可能的,但休眠不允许这样做。

任何人都可以帮忙吗?我们不想为此在A中写任何东西。


答案 1

休眠仅沿定义的关联级联。如果 A 对 B 一无所知,那么你对 A 所做的任何事情都不会影响 Bs。

因此,Pascal的建议是做你想做的事的最简单方法:

<class name="A" table="tbl_A">
  ...
  <set name="myBs" inverse="true" cascade="all,delete-orphan">
    <key column="col1"/>
    <one-to-many class="B"/>
  </set>
</class>

<class name="B" table="tbl_B">
  ...
  <many-to-one name="a" class="A" column="col1" not-null="true"/>
</class>

请注意,在原始代码中设置 on 不会执行您想要的操作 - 它会告诉 Hibernate“如果 B 被删除,则删除 A”,这可能会导致约束冲突(如果有任何其他 B 链接到该 A)。cascade="delete"B

如果你绝对不能将Bs的集合添加到A(尽管我真的想不出这种情况的情况),你唯一的其他选择是在外键级别定义从A到B的级联删除;然后,当您的A被删除时,您的Bs将被删除。

然而,这是一个相当丑陋的解决方案,因为你必须非常小心如何在Hibernate中删除A:

  1. 在删除 A 之前,必须刷新会话(对 B 进行挂起的更新可能会导致错误或 A 和一些 B 在后台重新插入)
  2. 链接到 A 的所有 B(并且由于您没有维护来自 A 端的关系,这意味着所有 B)都必须从所有活动会话和第 2 级缓存中逐出。

答案 2

我认为你需要从A到B的关联。cascade="all,delete-orphan"one-to-many


推荐