UnsupportedOperationException when merging an existing Hibernate model object?

After an upgrade from Hibernate 3 to 4, we're working through a few kinks that popped up along the way. One that has us particularly stumped is an UnsupportedOperationException, where an existing object is pulled from the database, tweaked, and merged.

The problem is that Hibernate appears to be adding an object to an AbstractList

This only seems to happen to one particular object type, when saved in our DAO, but as best as we can tell:

  1. We're not using any sublist() or asList() methods that would cause an immutable instance to be created.
  2. Examining the object that's being saved (which is enormous and has many children) I don't think that any of its children items are AbstractList types.

Here are the code snippets around the stack points:

HibernateDao.save():

@Transactional
public void save(T item) {
    try {
        getSessionFactory().getCurrentSession().merge(item);
    } catch (Exception ex) {
        LOGGER.debug("Unable to merge", ex);
        LOGGER.warn("Unable to merge item, saving instead. (Of type " + item.getClass() + ")");
        getSessionFactory().getCurrentSession().saveOrUpdate(item);
    }
}

Our User item, which is being saved, has a number of children items defined like so:

@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, Project> associatedProjects = new HashMap<String, Project>();

The Project class has other similarly-annotated children, but everything has CascadeType.ALL, and LazyCollectionOption.FALSE defined.

Here is the (quite tall) stack trace:

Note that our code begins with com.company.application

06/04 18:15:45 DEBUG [Thread-19258] hibernate.HibernateDao.save- Unable to merge
java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)
        at java.util.AbstractList.add(AbstractList.java:108)
        at org.hibernate.collection.internal.PersistentBag.add(PersistentBag.java:292)
        at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:496)
        at org.hibernate.type.CollectionType.replace(CollectionType.java:563)
        at org.hibernate.type.AbstractType.replace(AbstractType.java:178)
        at org.hibernate.type.TypeHelper.replaceAssociations(TypeHelper.java:261)
        at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:398)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:221)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:282)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
        at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
        at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
        at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
        at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
        at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
        at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
        at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
        at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
        at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
        at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
        at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
        at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
        at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
        at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
        at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
        at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
        at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
        at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:904)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:888)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:892)
        at com.company.hibernate.HibernateDao.save(HibernateDao.java:129)
        at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy53.save(Unknown Source)
        at com.company.application.UserManager.save(UserManager.java:46)
        at sun.reflect.GeneratedMethodAccessor67.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy66.save(Unknown Source)
        at com.company.application.UserOperationController.saveUser(UserOperationController.java:533)

We're not sure where the AbstractList is coming from, or how we're responsible. Are there any potential pitfalls when working with Hibernate 4 (this issue is new since the upgrade) that could result in partially-unmodifiable objects? Or that would cause Hibernate to act in a way that results in it attempting to create unmodifiable instances of objects?

In this block of code:

@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, Project> associatedProjects = new HashMap<String, Project>();

how about to add this.

@OneToMany(cascade = CascadeType.ALL)

*****@JoinColumn(name="")***** 

@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, Project> associatedProjects = new HashMap<String, Project>();

java, when merging an existing Hibernate model object? hibernate.hibernatedao. save- unable merge java.lang.unsupportedoperationexception� We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand

I ran into this same issue (with Sets not Lists) and it seems like Hibernate's Persistent variant of the collection in question attempts to delegate to an abstract base class that doesn't implement the add method. The solution I found was to set the data member to null, do a merge and then set the data member back to the new list that I wanted it to contain. The rather obvious downside is that I blow away all of the records even if I only want to add or remove one. The upside is that it actually works...

java: UnsupportedOperationException when merging an existing , After an upgrade from Hibernate 3 to 4, we're working through a few kinks that popped up when merging an existing Hibernate model object? I have an application using hibernate and hazelcast that works fine but when I'm running other application that uses spring mvc and jdbc template it is not working well Tomcat log: `INFO: [LOCAL] [dev] [3.5.1] Prefer IPv4 stack is true.

Use this transaction type:

@javax.transaction.Transactional(Transactional.TxType.REQUIRES_NEW)

Hibernate ORM 5.4.20.Final User Guide, Combining multiple JPA entity graphs into one Hibernate is an Object/ Relational Mapping solution for Java environments. 'F' || code == 'f' ) { return FEMALE; } throw new UnsupportedOperationException( "The code " + code + " is not supported! To ignore non-existing parent entity references, even though not really� JPA’s merge method copies the state of a detached entity to a managed instance of the same entity. Hibernate, therefore, executes an SQL SELECT statement to retrieve a managed entity from the database. If the persistence context already contained a managed instance of the entity, Hibernate uses the existing one instead.

Hibernate ORM 5.2.18.Final User Guide, Hibernate is an Object/Relational Mapping solution for Java environments. 'F' || code == 'f' ) { return FEMALE; } throw new UnsupportedOperationException( "The code " + It's not possible to combine the @Filter and @Cache collection annotations. To ignore non-existing parent entity references, even though not really� Sometimes this programming model is inefficient since it would require both an SQL SELECT (to load an object) and an SQL UPDATE (to persist its updated state) in the same session. Therefore Hibernate offers an alternate approach, using detached instances.

How do Set and List collections behave with JPA and Hibernate , Hibernate is a great ORM tool, and it eases development When it comes to controlling the persist/merge part of the association, there are two If your domain model requires using a List than a Set will break your Objects. requireNonNull(child, "Persistent collection cannot work with null elements");. This confirms that hibernate was tracking the object for any changes and at the time of committing transaction, this value got saved. Hibernate Merge. Hibernate merge can be used to update existing values, however this method create a copy from the passed entity object and return it. The returned object is part of persistent context and tracked

Exception being thrown because of a null value in the hibernate , My problem is happening when I update an entity. It was working Maybe somebody can provide some insight on hibernate's merge. The exception I'm getting UnsupportedOperationException: null. at java.util. The thing about null means that there is no message given to the exception object. Look at� Hibernate is a full object/relational mapping solution that not only shields the developer from the details of the underlying database management system, but also offers state management of objects. This is, contrary to the management of SQL statements in common JDBC/SQL persistence layers, a natural object-oriented view of persistence in Java

Comments
  • From the stacktrace, it sounds like the merge is being cascaded to other objects associated with the User. Do you have any collections mapped as a Bag type?
  • For me it looks like an error in hibernate, which would make it ugly to go around that issue. I think the only chance to get is, is to find out which child or grand child of item produces this error. For tests you can manually merge the children (and perhaps grand children) of item instead of letting cascade to that.
  • @mattb We definitely don't have any Bag types - only HashMap and ArrayList. Examining the object right before Hibernate merges it, it seems as though many of the ArrayList types were actually being wrapped by Hibernate in a PersistentBag. (But, underneath the bags were actual concrete ArrayList implementations, so I didn't see this to be a problem.)
  • @Johanna Thanks - I'll examine the object in the debugger again, and see if I can actually determine which child is causing issues.
  • you probably know this by now, but for future readers, whenever you persist a List without specifying the @Order, Hibernate will treat it as a bag. And the AbstractList comes from the backing list used in PersistentBag.