【发布时间】:2011-01-05 03:13:23
【问题描述】:
我有这些实体
class Foo{
Set<Bar> bars;
}
class Bar{
Foo parent;
String localIdentifier;
}
有了这个映射(抱歉,没有注释,我老了):
<class name="Foo">
...
<set name="bars" cascade="all-delete-orphan" lazy="false" inverse="true">
<key>...</key>
<one-to-many class="Bar"/>
</set>
</class>
<class name="Bar">
...
<property name="localIdentifier" column="local_identifier"/>
<many-to-one name="parent" column="parent_id" />
</class>
我对 2 列也有唯一约束:local_identifier 和 parent_id(不是每列的唯一约束,而是包含两者的单个唯一约束,例如,不允许有 2 行具有相同父级和相同 localIdentifier)
alter table bar add constraint unique_bar unique (parent_id, local_identifier)
以及使用它们的这段代码:
//foo is persistent, foo id = 1
Bars bars = foo.getBars();
bars.clear(); // bars contained 1 item [parent_id = 1, local_identifier = "a"]
Bar newBar = new Bar();
newBar.setParent(foo);
newBar.setLocalIdentifier("a");
bars.add(newBar);
现在,出于某种原因,Hibernate 不会按照调用顺序执行操作。它不会在add()(插入)之前执行clear()(删除),反之亦然,它首先尝试插入,得到ConstraintViolationException
我知道在 bars.clear(); 之后添加一点 session.flush() 可以解决此问题,但在这种情况下,我无法以不丑陋的方式访问会话。
那么冲洗是唯一的解决方案吗?还是有尊重动作顺序的 Hibernate 版本?
更新: 顺便说一句,取消引用集合将导致来自https://www.hibernate.org/117.html#A3 的 HibernateException:
我得到 HibernateException:不要 取消引用集合 cascade="all-delete-orphan" 这个 如果你加载一个对象会发生 一个级联=“所有删除孤儿” 收集,然后删除 参考收藏。别 替换这个集合,使用 clear() 所以孤儿删除算法可以 检测你的变化。
【问题讨论】:
-
我认为冲洗是这里唯一的选择
标签: hibernate unique-constraint