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>
现在假设我有一个User对象与一个或多个Email对象相关联,其中至少有一个对象具有已删除属性的'true'值。当我在User对象上调用session.delete()时会发生以下哪两个?
一方面,方案1)忽略where条件,根据域模型可能不正确。但是在方案2)中,如果父项被删除,并且子(email)表的连接键上存在外键约束,则delete命令将失败。哪个发生了,为什么?这只是Hibernate功能如何模棱两可的另一个例子吗?
答案 0 :(得分:4)
我没有测试映射,但在我看来,正确的(默认)行为应该是忽略where
条件并删除所有子记录(这是避免FK约束违规的唯一选择)删除父母)。从商业角度来看,这可能不是“正确的”,但另一种选择并不“正确”,因为它只是不起作用。
总而言之,映射本身看起来不连贯。您应该不级联delete
操作(并手动处理子Email
的删除)。
或者,我认为这可能是最正确的行为,您应该实现User
和相关{{1}的软删除 }}。像这样:
Email
这里做了什么:
<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>
覆盖默认删除以更新标志而不是真正的删除(软删除)。sql-delete
过滤实体和关联,仅获取未被软删除的实体。这受到Soft deletes using Hibernate annotations的启发。虽然没经过测试。