Hibernate - 使用 all-delete-orphan 清除集合然后添加到它会导致 ConstraintViolationException

2024-02-06

我有这些实体

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() 所以孤儿删除算法可以 检测你的改变。


我想除了冲水没有其他选择

From here https://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems?_sscc=t#jive_content_id_Hibernate_is_violating_a_unique_constraint:

Hibernate 违反了一个独特的约束!

Hibernate 并不完全是这样 聪明且具有独特的约束 是带有外键的。有时你 可能需要给出一点提示。

违反唯一约束可能 如果两个对象都被 更新,一个是“释放”一个值 另一个是“获得”相同的 价值。解决方法是flush()这 更新后手动会话 第一个对象和更新之前 第二。

(This kind of problem occurs rarely in practice.)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate - 使用 all-delete-orphan 清除集合然后添加到它会导致 ConstraintViolationException 的相关文章

随机推荐