Hibernate 3.6.6.Final(JBoss 6.1)merge()瞬态对象树

Hibernate 3.6.6.Final(JBoss 6.1)merge()瞬态对象树,hibernate,jakarta-ee,stateless-session-bean,Hibernate,Jakarta Ee,Stateless Session Bean,我尝试用Hibernate的merge()方法保存对象树。实体Auftrag(英文意思是“订单”)包含Auftragsposition对象的集合,映射为cascade=“all delete orphan 持久化发生在通过RMI调用的无状态会话bean中。该方法打开一个新的(干净的)会话实例。当保存一个已经存在的顺序时,merge()尝试从DB加载实体,然后将刚加载的依赖顺序位置与会话的持久化上下文相关联。稍后,当merge()如果操作级联到订单位置,则会发生UnuniqueObjectExce

我尝试用Hibernate的merge()方法保存对象树。实体
Auftrag
(英文意思是“订单”)包含
Auftragsposition
对象的集合,映射为
cascade=“all delete orphan

持久化发生在通过RMI调用的无状态会话bean中。该方法打开一个新的(干净的)
会话
实例。当保存一个已经存在的顺序时,merge()尝试从DB加载实体,然后将刚加载的依赖顺序位置与会话的持久化上下文相关联。稍后,当merge()如果操作级联到订单位置,则会发生UnuniqueObjectException(因为临时订单位置不同于Hibernate加载的订单位置)

saveOrUpdate()会产生类似的结果

是否存在智能(一行或尽可能少的代码行)解决方案?或者是否必须解决该行为,例如通过在对象树上递归并首先保存(与会话关联)瞬态对象

(注:我现在得到了这个异常,因为我抛出了一个名为
AuftragEntityPersister
的旧的定制子类,它从数据库中清除了整个对象树,然后再次插入了内容,可能是为了解决这个问题。)

参见异常堆栈跟踪:

13:54:16,052 ERROR [de.redacted.services.persistence.auftrag.AuftragPersistenceSessionBean] Rolling back due to Hibernate-Exception: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [de.redacted.domain.auftrag.Auftragsposition#de.redacted.domain.angebot.AngebotsPositionPK@b4000000]
  at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:190) [:3.6.6.Final]
  at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:415) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:341) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:303) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:258) [:3.6.6.Final]
  at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:877) [:3.6.6.Final]
  at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:859) [:3.6.6.Final]
  at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:279) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204) [:3.6.6.Final]
  at org.hibernate.engine.Cascade.cascade(Cascade.java:161) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:630) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:490) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:255) [:3.6.6.Final]
  at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:84) [:3.6.6.Final]
  at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:867) [:3.6.6.Final]
  at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:851) [:3.6.6.Final]
  at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:855) [:3.6.6.Final]
  at de.redacted.services.persistence.auftrag.AuftragPersistenceSessionBean.saveAuftrag(AuftragPersistenceSessionBean.java:1145) [:]
  at de.redacted.services.persistence.auftrag.AuftragPersistenceSessionBean.saveAuftrag(AuftragPersistenceSessionBean.java:873) [:]
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_21]
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_21]
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_21]
  at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_21]
  at org.jboss.invocation.Invocation.performCall(Invocation.java:386) [:6.1.0.Final]
  at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:233) [:6.1.0.Final]
  at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:156) [:6.1.0.Final]
  at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:173) [:6.1.0.Final]
  at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:63) [:6.1.0.Final]
  at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:121) [:6.1.0.Final]
  at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:350) [:6.1.0.Final]
  at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:181) [:6.1.0.Final]
  at org.jboss.ejb.plugins.SecurityInterceptor.process(SecurityInterceptor.java:228) [:6.1.0.Final]
  at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:211) [:6.1.0.Final]
  at org.jboss.ejb.plugins.security.PreSecurityInterceptor.process(PreSecurityInterceptor.java:100) [:6.1.0.Final]
  at org.jboss.ejb.plugins.security.PreSecurityInterceptor.invoke(PreSecurityInterceptor.java:84) [:6.1.0.Final]
  at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:205) [:6.1.0.Final]
  at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:138) [:6.1.0.Final]
  at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:650) [:6.1.0.Final]
  at org.jboss.ejb.Container.invoke(Container.java:1072) [:6.1.0.Final]
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_21]
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_21]
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_21]
  at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_21]
  at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157) [:6.0.0.GA]
  at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96) [:6.0.0.GA]
  at org.jboss.mx.server.Invocation.invoke(Invocation.java:88) [:6.0.0.GA]
  at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:271) [:6.0.0.GA]
  at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:670) [:6.0.0.GA]
  at org.jboss.invocation.unified.server.UnifiedInvoker.invoke(UnifiedInvoker.java:232) [:6.1.0.Final]
  at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:967) [:6.1.0.Final]
  at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:791) [:6.1.0.Final]
  at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:744) [:6.1.0.Final]
  at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:586) [:6.1.0.Final]
  at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:234) [:6.1.0.Final]
状态更新:

如果这就是问题的全部,我会通过在对象树上递归(至少到一定深度)来解决它。不好,但至少很少见

由于有其他一些不好的需求(这是一个遗留数据模型),我最终保留了定制的Persister子类