Hibernate:更新对象的最佳方法

4

假设我有:

// all objects have valid mapping to database
public class A {
   private int id;
   private String name;
   private List<B> chidlren1;
   private List<C> children2;
}

在我的控制器的更新方法中,我必须更新特定对象,但是我将其新值存储在会话变量中,例如另一个A对象。

那么问题是如何有效地从另一个对象更新该特定对象?下面的代码是否有效?

A old = dao.get(id);
A temp = getFromSession();

old.Name = temp.Name;
old.Children1 = temp.Children1;
old.Children2 = temp.Children2;
dao.update(old);

另一个问题是,如果之前的方法正确,那么Hibernate会首先从子表中删除所有记录并添加新记录,还是它可以自动更新/插入新记录并删除已删除的记录?

谢谢

更新#1:假设temp的子集合与old的子集合不同怎么办?


如果存在当前记录,dao.update(old) 将实际更新该记录。不会插入新记录。 - Rakesh
我谈到了子集合和子表行。请参见UPD#1。 - nKognito
1
它不会从子表中删除所有记录。因为,它将有多个A实例的记录。但它会修改表以反映对当前A实例所做的更改。如果记录不在新集合中,则会将其删除。 - Bhesh Gurung
2个回答

4

如果你的类型为AB的子实体集合已正确设置id,并在这些实体上指定了cascade=MERGE,那么你应该能够使用merge方法,例如:

A updatedEntity = dao.merge(yourObjectFromTheHttpSession);

话虽如此,在过去,我不得不手动调整相关的集合,以正确处理新进实体并删除现有实体,而无法依赖于 hibernate 自动处理所有事情,因此每个人的情况可能会有所不同。

从文档中可以得到以下信息:

将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久实例,则会加载该实例。返回持久实例。如果给定实例未保存,则保存副本并将其作为新的持久实例返回。给定的实例不会与会话关联。如果使用 cascade="merge" 映射关联,则此操作会级联到关联实例。

此方法的语义由 JSR-220 定义。


0

我同意Rakesh的观点。 如果你还有疑虑,可以设置"show_sql = true"(一个Hibernate属性),这样你就可以看到SQL语句了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接