简体   繁体   中英

Updating an object that contains a list in Hibernate

In my GWT application, I pass an Object to the server for persistence with Hibernate. This Object contains a list of another object. Each element in the list contains a Map which is another Hibernate table.

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
  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:

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?

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
  • foo is not a managed object, neither is anything in 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). 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.

Instead of manually tweaking the managed object's list, use merge(foo) to update the persistent instance's state with the unmanaged instance. From the Hibernate manual :

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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