休眠 - 清除收集与全删除,孤儿,然后添加到它会导致ConstraintViolationException

StackOverflow https://stackoverflow.com/questions/2065254

  •  20-09-2019
  •  | 
  •  

我有这些实体

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_identifierparent_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并不在他们被调用的顺序执行的东西。它不clear()(插入),但反之亦然之前执行add()(删除)时,它首先试图插入,获得一个ConstraintViolationException

我知道加入session.flush()后有点bars.clear();,可以解决这个问题,但在这种情况下,我有一个非丑陋的方式没有访问会话。

所以是齐平是唯一的解决办法?或者是有一个尊重的动作的顺序一个Hibernate版本?

<强>更新 顺便说一句,提领该集合将导致HibernateException的从 https://www.hibernate.org/ 117.html#A3

  

我得到HibernateException的:不要   解引用一个集合   级联= “全删除-孤儿”此   如果您加载一个对象会发生   级联=“全删除,孤儿”   集合,然后删除   参考集合。别   更换此集合,使用clear()   所以孤儿删除算法可以   检测更改。

有帮助吗?

解决方案

我想没有替代冲洗

这里

  

<强>休眠违反唯一约束!

  Hibernate是不是很   巧用唯一约束,因为它   与外键。有时候你   可能需要给一点提示。

     

一个唯一约束违反能   如果两个对象都存在发生   更新,一个是“释放”的值   另一种是“获得”相同   值。一种解决方法是为齐平()的所述   更新后的会话手动   第一对象和更新前   第二。   

  (这种问题很少出现在   做法。)

其他提示

如果你想避免在这里冲洗会议,尝试更换整个列表(new List<Bar>()而不是Clear())。休眠应该增加新的前实际删除在一杆中的所有项目。只是一种尝试,不知道是否可行。

如果您使用的是Oracle,你也可以使用延迟约束,直到事务被提交推迟的约束检查。不知道是否/如何被其他数据库的支持。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top