简体   繁体   English

在Hibernate中更新包含列表的对象

[英]Updating an object that contains a list in Hibernate

In my GWT application, I pass an Object to the server for persistence with Hibernate. 在我的GWT应用程序中,我将对象传递给服务器以保持Hibernate的持久性。 This Object contains a list of another object. 该对象包含另一个对象的列表。 Each element in the list contains a Map which is another Hibernate table. 列表中的每个元素都包含一个Map,这是另一个Hibernate表。

In order to do this transaction, it is my understanding that I must first: 为了进行此交易,我的理解是我必须首先:

  1. Do a lookup to get the persistent object from the database via Hibernate 查找以通过Hibernate从数据库中获取持久对象
  2. Modify the object 修改对象
  3. Update the object via Hibernate 通过休眠更新对象

Here is some quick code on what I'm doing: 这是关于我在做什么的一些快速代码:

public void saveOrUpdateObject(final Foo foo)
{
   Session session = sessionFactory.getCurrentSession();
   session.beginTransaction();

   Object lookup = myDAO.getObject(foo.getUniqueValue());

   if (lookup != null) {
      lookup.getList().clear();
      lookup.addAll(foo.getList());

      myDAO.update(lookup);
   }
   else {
      myDAO.save(foo);
   }
}

Using this method, I occasionally get a HibernateException: 使用这种方法,我偶尔会得到一个HibernateException:

org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: my.Foo.list

What is the proper way to update an Object that contains a collection using Hibernate? 使用Hibernate更新包含集合的Object的正确方法是什么?

The problem has to do with having both managed and unmanaged objects: 问题与同时拥有托管和非托管对象有关:

  • lookup is a managed object, as is lookup.list and everything in it lookup是一个托管对象, lookup.list以及其中的所有内容
  • foo is not a managed object, neither is anything in foo.list foo不是托管对象,foo.list中也不是任何对象

When you call lookup.getList().clear() , you are signalling to Hibernate that everything in that managed list needs to be deleted (due to the all-delete-orphan cascading). 当您调用lookup.getList().clear() ,您向Hibernate发信号说该托管列表中的所有内容都需要删除(由于all-delete-orphan级联的级联)。 However, you then come back and add a bunch of stuff to that (managed) list, including some things that were probably already there. 但是,您然后返回并向该(托管)列表添加一堆东西,其中包括可能已经存在的一些东西。 Hibernate gets confused and throws an Exception. Hibernate感到困惑,并引发异常。

Instead of manually tweaking the managed object's list, use merge(foo) to update the persistent instance's state with the unmanaged instance. 与其手动调整托管对象的列表,不如使用merge(foo)用非托管实例更新持久实例的状态。 From the Hibernate manual : Hibernate手册中

if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance 如果存在与会话当前关联的具有相同标识符的持久实例,则将给定对象的状态复制到持久实例上

Merging puts the responsibility of figuring out which state is updated onto Hibernate. 合并负责确定哪个状态已更新到Hibernate。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM