当前位置: 首页 > 面试题库 >

休眠-清除具有all-delete-orphan的集合,然后将其添加到其中会导致ConstraintViolationException

闽阳州
2023-03-14
问题内容

我有这些实体

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版本尊重操作顺序?

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


我得到了HibernateException:不要用cascade =“ all-delete-orphan”取消引用集合。
如果您加载了带有cascade =“ all-delete-
orphan”集合的对象,然后删除对该集合的引用,则会发生这种情况。不要替换此集合,请使用clear(),以便孤立删除算法可以检测到您的更改。


问题答案:

我想没有其他方法可以冲洗

从这里:

Hibernate违反了唯一约束!

Hibernate的唯一约束并不像外键那么聪明。有时您可能需要给出一些提示。

如果两个对象都被更新,一个对象在“释放”一个值,而另一个对象在“获取”相同的值,则可能发生唯一约束冲突。一种解决方法是在更新第一个对象之后并在更新第二个对象之前手动
冲洗 会话。

(这种问题在实践中很少发生。)



 类似资料:
  • 问题内容: 我与CohortGroup和Employee有很多关系。每当我将Employee插入CohortGroup时,冬眠都会从解析表中删除该组,然后再次插入所有成员,再加上新成员。为什么不只是添加新的呢? 组中的注释: 员工的另一边 代码嗅探 下面是日志中报告的SQL 这种接缝的效率很低,并且会引起一些问题。如果有人提出将某员工添加到该组的要求,那么有些人将被改写。 诸如equals和has

  • 问题内容: 尝试更新我的实体时遇到以下问题: 我有一个父实体,并且有一些子实体。当我尝试更新它时,我将获取所有要设置为此集合的引用并进行设置。 以下代码表示我的映射: 根据此,我尝试仅清理Set <..>:如何“可能”解决问题,但没有成功。 如果您有任何想法,请告诉我。 谢谢! 问题答案: 实际上,我的问题是关于实体的等于和哈希码。遗留代码会带来很多问题,永远不要忘记对其进行检查。我所做的只是保留

  • 问题内容: 我与CohortGroup和Employee有很多关系。每当我将Employee插入CohortGroup时,hibernate都会从解析表中删除该组,然后再次插入所有成员以及新成员。为什么不只是添加新的呢? 组中的注释: 员工的另一边 代码嗅探 下面是日志中报告的SQL 这种接缝的效率很低,并且会引起一些问题。如果有人提出要求将雇员添加到组中,则有些人将其改写。 诸如equals和h

  • 问题内容: 我有两个实体,消息和用户。用户与消息有一个ManyToMany关系(一个用户可以有多个消息),而消息(现在,为了使其不那么复杂)与用户有一个ManyToMany关系(可以将一条消息发送给多个用户)。 我正在使用@JoinTable加入这两个实体,但是,我想在连接表中添加一个“状态”列,以告知该消息是否是新消息,已读消息等。我当时正在考虑将该列放入Message实体中,但是,我认为这可能

  • 问题内容: 我想将背景图像添加到我的JFrame中,但是当我使用下面的代码进行操作时,我无法添加其他元素,例如JLabel或JTextField。 您能否告诉我是否还有另一种方法可以将JTabbedPane添加到具有背景的JFrame中? 谢谢。 问题答案: 像这样? 附录:“通常您会先调用,但是由于图像将覆盖整个背景,因此无需这样做。” — [camickr] 如果仅创建自定义UI来添加背景图像

  • 我试图创建一组int数组,问题是,如果我尝试这样做: 那么s有两个对象,但应该只有一个。注意:它是否是HashSet并不重要 现在如果我试着用ArrayList做这个 那么s有一个对象。 我想了一种方法来避免第一个代码中的错误,并将每个数组的hashcode存储在hashset中,如下所示: 它适用于第一种情况(1,2,3),但在有碰撞的情况下它不起作用,所以我必须管理碰撞。所以,我认为我正在做的