一尘不染

如何在hibernate中的多对一映射上定义逆级联删除

hibernate

我有两个类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。记住这一点,我们打算在删除与A关联的B时将其删除。如果我可以在B中的多对一关联中定义inverse =“
true”,但hibernate则不允许这样做,这是可能的。

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


阅读 226

收藏
2020-06-20

共1个答案

一尘不染

hibernate仅沿着定义的关联进行级联。如果A对B不了解,那么您对A所做的任何事情都不会影响B。

因此,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>

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

如果您绝对不能向A添加B的集合(尽管我真的不认为会是这种情况),您唯一的另一种选择是在外键级别上定义从A到B的级联删除。然后,当您删除A时,您的B将被删除。

但是,这是一个非常丑陋的解决方案,因为您必须非常小心在Hibernate中删除A的方式:

  1. 必须先刷新会话,然后才能删除A(对B的待定更新可能会导致错误,或者A和某些B在后台重新插入)
  2. 必须从所有活动会话和第二级缓存中逐出与您的A链接的所有B(并且由于您未从A端维护关系,这意味着 所有 B)。
2020-06-20