Hibernate - 使用all-delete-orphan清除集合,然后添加到它会导致ConstraintViolationException [英] Hibernate - clearing a collection with all-delete-orphan and then adding to it causes ConstraintViolationException

查看:133
本文介绍了Hibernate - 使用all-delete-orphan清除集合,然后添加到它会导致ConstraintViolationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这些实体

  class Foo {
Set< Bar>酒吧;
}

class Bar {
Foo parent;
String localIdentifier;
}

有了这个映射(抱歉,没有注释,我老掉牙):

 < class name =Foo> 
...
< key> ...< / key>
<一对多课程=Bar/>
< / set>
< / class>


< class name =Bar>
...
< property name =localIdentifiercolumn =local_identifier/>
< / class>

我也对2列有一个唯一的约束: local_identifier parent_id (不是每个唯一约束,而是包含两个唯一约束,例如,不允许具有相同父级和相同localIdentifier的2行) p>

  alter table bar添加约束unique_bar unique(parent_id,local_identifier)

以下代码使用它们:

  // foo是持久的, foo id = 1 
Bars bars = foo.getBars();
bars.clear(); // bar contains 1 item [parent_id = 1,local_identifier =a]
Bar newBar = new Bar();
newBar.setParent(foo);
newBar.setLocalIdentifier(a);
bars.add(newBar);

现在,由于某种原因,Hibernate并不按照它们被调用的顺序执行。它不会在 add()(insert)之前执行 clear()(delete),反之亦然,它首先尝试插入,得到 ConstraintViolationException



我知道添加一些会话。 flush() bars.clear(); 之后,可以解决这个问题,但在这种情况下,我无法访问非会话丑陋的方式。

那么冲洗是唯一的解决方案?或者是否存在一个尊重操作顺序的Hibernate版本?



更新:
顺便说一下,取消引用集合会导致在来自 https://www.hibernate.org/117.html#A3 的HibernateException中:


我得到HibernateException:不
使用
取消引用集合cascade =all- delete-orphan
如果您使用
a cascade =all-delete-orphan
集合加载一个对象,然后将
引用移除采集。不要
替换这个集合,请使用clear()
,这样孤儿删除算法可以
检测到您的更改。



解决方案

我想没有其他的办法可以冲洗了 here


Hibernate违反了唯一的约束!
Hibernate并不像
那样聪明,只有
有外键。有时你可能需要给出一点提示。


如果两个对象都是
更新,一个是释放一个值
,并且其他的是获得相同的
值。解决方法是在更新
第一个对象并更新
秒之前手动刷新(b)$(b $ b)会话。


(这种问题在
练习中很少出现)。


I have these entities

class Foo{
    Set<Bar> bars;
}

class Bar{
    Foo parent;
    String localIdentifier;
}

With this mapping (sorry, no annotations, I'm old fashioned):

<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>

I also have a unique constraint on 2 columns: local_identifier and parent_id (not a unique constrain on each, but a single unique constrain containing both, e.g. no 2 rows with the same parent and same localIdentifier are allowed)

alter table bar add constraint unique_bar unique (parent_id, local_identifier)

And this code that uses them:

//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);

Now, for some reason, Hibernate doesn't execute things in the order they were called. It doesn't execute the clear() (delete) before the add() (insert) but vice versa, it first tries to insert, getting a ConstraintViolationException

I know adding a little session.flush() after bars.clear(); , could fix this, but in this case, I have no access to the session in a non ugly way.

So is flush is the only solution? or is there a Hibernate version that respects the order of actions?

Update: By the way, dereferencing the collection will result in a HibernateException from https://www.hibernate.org/117.html#A3:

I get HibernateException: Don't dereference a collection with cascade="all-delete-orphan" This will happen if you load an object with a cascade="all-delete-orphan" collection and then remove the reference to the collection. Don't replace this collection, use clear() so the orphan-deletion algorithm can detect your change.

解决方案

I guess there is no alternative to flushing

From here:

Hibernate is violating a unique constraint!

Hibernate isn't quite as clever with unique constraints as it is with foreign keys. Sometimes you might need to give a little hint.

A unique constraint violation could occur if two objects are both being updated, one is "releasing" a value and the other is "obtaining" the same value. A workaround is to flush() the session manually after updating the first object and before updating the second.

(This kind of problem occurs rarely in practice.)

这篇关于Hibernate - 使用all-delete-orphan清除集合,然后添加到它会导致ConstraintViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆