将delete-orphan与where条件相结合

Ant*_*ric 5 java orm hibernate data-mapping

Hibernate映射问题,其中行为是模糊的和/或危险的.我有一对多关系,具有级联删除孤立条件和where条件限制集合中的项目.这里映射 -

<hibernate-mapping>
 <class name="User" table="user" > 

  <!-- properties and id ... -->

   <set table="email" inverse="true" cascade="all,delete-orphan" where="deleted!=true">
      <key column="user_id">
      <one-to-many class="Email"/>
   </set>

 </class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)

现在假设我有一个与一个或多个Email对象关联的User对象,其中至少有一个对于deleted属性具有'true'值.当我在User对象上调用session.delete()时,会发生以下哪两个?

  1. 将删除用户和所有电子邮件对象,包括已删除= true的对象
  2. 将删除用户和已删除的电子邮件对象!= null.

一方面,方案1)忽略where条件,根据域模型可能不正确.但是在方案2)中,如果父项被删除,并且子(email)表的连接键上存在外键约束,则delete命令将失败.哪个发生了,为什么?这只是Hibernate功能如何模糊的另一个例子吗?

Pas*_*ent 4

我没有测试映射,但在我看来,正确的(默认)行为应该是忽略where条件并删除所有子记录(这是删除父记录时避免违反 FK 约束的唯一选择)。从商业角度来看,这可能不“正确”,但另一个选项也不“正确”,因为它不起作用。

总而言之,映射本身看起来不连贯。您不应该级联操作delete(并手动处理子项的删除Email)。

或者,我认为这可能是最正确的行为,您应该对和关联的. 像这样的东西:UserEmail

<hibernate-mapping>
  <class name="User" table="user" where="deleted<>'1'"> 

    <!-- properties and id ... -->

    <set table="email" inverse="true" cascade="all,delete-orphan" where="deleted<>'1'">
      <key column="user_id">
      <one-to-many class="Email"/>
    </set>
    <sql-delete>UPDATE user SET deleted = '1' WHERE id = ?</sql-delete>
  </class>

  <class name="Email" table="email" where="deleted<>'1'"> 

    <!-- properties and id ... -->

    <sql-delete>UPDATE email SET deleted = '1' WHERE id = ?</sql-delete>
  </class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)

这里做了什么:

  • 我们使用更新sql-delete标志来覆盖默认删除,而不是真正的删除(软删除)。
  • 我们使用 来过滤实体和关联,where以仅获取尚未软删除的实体。

这是受到使用 Hibernate 注释的软删除的启发。虽然没有测试过。

参考