Hibernate version: 3.2.2 GA
Annotations version: 3.2.1 GA
EntityManager version: 3.2.1 GA
For reasons explained here
http://forum.hibernate.org/viewtopic.php?t=970995 I am trying to use Session.saveOrUpdate() on a Hibernate Session obtained from an EJB3 EntityManager. Unfortunately I ran into the stack trace below with code that has no problems when I use EntityManager.merge(). The only code difference is in the method com.lggi.esp.services.ejb.persistence.PersistenceBean.persist() you can see in the stack trace. I debugged Hibernate and found that somehow a the same Hibernate Session was used across multiple bean calls within our JBoss server. So previous instance of class Action stayed in the Session's cache. Since the bean calls were against a remote interface, it seems that the instance of Action was serialized several times, resulting in the NonUniqueObjectException below.
To make it clear, the code in ActionExecutionManager.updateAction() looks roughly like this:
Code:
// Get the PersistenceBean
PersistenceService persistenceService = ...;
// Load an action, which goes into the Session cache.
Action action = persistenceService.find(Action.class, id);
...
// Getting NonUniqueObjectException in this call:
Action savedAction = persistenceService.persist(action);
So it looks like my bean calls are treated like remote calls by JBoss, while Hibernate treats them as local calls by keeping the same Session around. I realize this is not a typical usage, but could this be a Hibernate problem? Why is the Session kept around across multiple non-local calls?
Caused by: javax.ejb.EJBTransactionRolledbackException: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.lggi.esp.domain.processing.Action#5]
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:93)
at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:201)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.RoleBasedAuthorizationInterceptor.invoke(RoleBasedAuthorizationInterceptor.java:167)
at org.jboss.ejb3.security.RoleBasedAuthorizationInterceptor.invoke(RoleBasedAuthorizationInterceptor.java:108)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:131)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:58)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
at $Proxy220.persist(Unknown Source)
at com.lggi.esp.services.ejb.processing.ActionExecutionManager.updateAction(ActionExecutionManager.java:255)
at com.lggi.esp.services.ejb.processing.ActionExecutionManager.handleFinishedEvent(ActionExecutionManager.java:218)
at com.lggi.esp.services.ejb.processing.ActionExecutionManager.eventFired(ActionExecutionManager.java:176)
at com.lggi.esp.services.ejb.processing.ActionExecutionManager.eventFired(ActionExecutionManager.java:43)
at com.lggi.esp.domain.util.event.DefaultEventManager$1.forwardEvent(DefaultEventManager.java:23)
at com.lggi.esp.domain.util.event.DefaultEventManager$1.forwardEvent(DefaultEventManager.java:22)
at com.lggi.esp.domain.util.event.SyncEventManager.fireEvent(SyncEventManager.java:123)
at com.lggi.esp.domain.processing.ActionBase.fire(ActionBase.java:200)
at com.lggi.esp.domain.processing.ActionBase.notifyFinalState(ActionBase.java:168)
at com.lggi.esp.domain.processing.Action.doCancel(Action.java:308)
at com.lggi.esp.domain.processing.Action.cancel(Action.java:293)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.sun.jmx.mbeanserver.StandardMetaDataImpl.invoke(StandardMetaDataImpl.java:414)
... 51 more
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.lggi.esp.domain.processing.Action#5]
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:577)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at com.lggi.esp.services.ejb.persistence.PersistenceBean.persist(PersistenceBean.java:113)
at com.lggi.esp.services.ejb.persistence.PersistenceBean$AjcClosure13.run(PersistenceBean.java:1)
at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:101)
at com.lggi.esp.services.aspects.security.SecurityAspect.aroundSecuredMethods(SecurityAspect.aj:150)
at com.lggi.esp.services.ejb.persistence.PersistenceBean.persist(PersistenceBean.java:108)
at sun.reflect.GeneratedMethodAccessor130.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
... 88 more