我有这些实体
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>
我对两列也有一个独特的约束:local_identifier
and parent_id
(不是每个都具有唯一约束,而是包含两者的单个唯一约束,例如不允许有具有相同父级和相同 localeIdentifier 的 2 行)
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 不会按照调用的顺序执行事物。它不执行clear()
(删除)之前add()
(插入)但反之亦然,它首先尝试插入,得到一个ConstraintViolationException
我知道加一点session.flush()
after bars.clear();
,可以解决这个问题,但在这种情况下,我无法以不丑陋的方式访问会话。
那么flush是唯一的解决办法吗?或者是否有一个 Hibernate 版本尊重操作顺序?
Update:顺便说一句,取消引用集合将导致 HibernateExceptionhttps://www.hibernate.org/117.html#A3 https://www.hibernate.org/117.html#A3:
我得到 HibernateException: Don't
取消引用集合
级联=“所有删除孤儿”这
如果你加载一个对象会发生
级联=“全部删除孤儿”
集合,然后删除
参考集合。不
替换这个集合,使用clear()
所以孤儿删除算法可以
检测你的改变。