gpt4 book ai didi

java - update() 和 merge 在更新 OneToMany 集合中的项目时表现不同

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:58:55 28 4
gpt4 key购买 nike

我有这样一个类:

@Entity
@Table(name="work")
public class Work {

@Id
@Column(name="id")
private String id;


@OneToMany(orphanRemoval=true ,mappedBy="work", cascade=CascadeType.ALL , fetch=FetchType.EAGER)
private List<PersonRole> personRoleList;
}

因为我的是一个 web 应用程序,当我更新(来自客户端)一个 personRoleList 项目并调用:

session.update(work); //`work` is in detached state

它不会更新现有的 personRoleList 项目,它实际上会添加一个新项目。

其他人也有同样的问题。引用:
using-saveorupdate-in-hibernate-creates-new-records-instead-of-updating-existi
jpa-onetomany-not-deleting-child

我尝试了所有建议的解决方案,但没有一个适合我。

但是然后我就尝试了:

 session.merge(work);  //replacing session.update(work)

而且它按预期工作。!!

这就是我感到困惑的地方。因为我找不到任何解释这种 OneToMany 关系情况下的行为差异(或者我可能错过了)。我阅读了一些线程以了解 update()merge() 之间的区别并浏览了文档。引用:

what-are-the-differences-between-the-different-saving-methods-in-hibernate

differences-among-save-update-saveorupdate-merge-methods-in-session

但仍然不清楚造成这种差异的行为模式/逻辑/步骤是什么?

最佳答案

Merge 尝试将当前 transient 对象与当前由 session 管理的持久对象关联起来,方法是将它们“合并”为一个实体。它的预期用途是当您有一个分离的对象一个附加的对象并希望解析它们时。

merge() 中,如果 session 中还没有托管实例,Hibernate 将从数据库中读取实体。在您的示例中,这将导致 Hibernate 急切地加载集合(由于 fetch=FetchType.EAGER)。然后当您的 session 结束时,Hibernate 将检查集合中的更改(由于 cascade=CascadeType.ALL)并将在数据库中执行适当的更新。

这不同于 update() 场景,因为在更新中,Hibernate 总是(默认情况下)假定对象是脏的并安排更新。此更新可能是导致在您的集合中创建新元素的原因 - Hibernate 在发布更新之前没有查看数据库以将集合带入 session 。

我敢打赌,您可以通过设置

获得所需的 update() 行为

select-before-update="true"

在您的类映射中或通过使用 lock 方法在进行更改之前将您的对象重新附加到 session 。

来自 的第 9 章 Java Persistence with Hibernate

item 对象在传递给之前或之后是否被修改并不重要更新()。这里重要的是对 update() 的调用将分离的实例重新附加到新的 session (和持久性上下文)。 hibernate 始终将对象视为脏对象并安排 SQL 更新,该更新将在刷新期间执行。您可以在图 9.8 中看到相同的工作单元。 您可能会感到惊讶并且可能希望 Hibernate 能够知道您修改了分离项的描述(或者 Hibernate 应该知道你做了不修改任何东西)。然而,新的 Session 及其新的持久性上下文没有这个信息。分离的对象也不包含您所做的所有修改的一些内部列表。需要数据库中的 UDPATE。避免此 UDPATE 语句的一种方法是使用 select-before-update="true"配置 Item 的类映射属性。 Hibernate 然后通过执行一个判断对象是否脏SELECT 语句并将对象的当前状态与当前数据进行比较-基态。

关于java - update() 和 merge 在更新 OneToMany 集合中的项目时表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31033382/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com