UserException - Object User#2 belongs to another EntityManager

#1

Hi!

Scenario's steps:

1. User goes to his profile, a JSF page.

2. @RequestScoped CDI bean UserDataB loads the current user of the session at each request, by using @Stateless bean UserC#findUserById(Long id)

3. JSF page's @RequestScoped CDI bean AnotherB loads trades of that user, by using @Stateless bean TradesC#findTradeByClient(User u).

### UserC and TradesC have their own @PersistenceContext EntityManager with the same unitName.

TradesC method needs an User, which is taken from UserDataB CDI. Problem on method execution, which runs a NamedQuery:

com.objectdb.o.UserException - Object 'com.pingushare.entity.p1.User#2' belongs to another EntityManager
at com.objectdb.o.MSG.d(MSG.java:61)

Why does this error happen, because there 2 independent transactions? I guess this should be a problem if, in the same transaction, an entity is passed into more EntityManagers, but here are 2 different transactions.

Shouldn't this work? Both @Stateless are method transactional, so each EM should be closed after each method's execution, therefore this error shouldn't appear.

Thanks.

#2

This exception is thrown only when mixing entity objects of different entity managers (which is forbidden, since every EntityManager manages its own space of managed objects, and a managed object of one EntityManager should not be used with another EntityManager).

It doesn't matter if both entity managers are associated with the same persistence unit.

Maybe you use one EntityManager to run the query, and a User object of another EntityManager as a parameter.

In addition, it may help to see the full stack trace of the exception (as requested in the posting instructions).

ObjectDB Support
#3

Well, the thing is that EM should be closed when the second @Stateless executes the method, so the User entity shouldn't be mixed.

Sorry for not posting the whole stack trace.

SEVERE: An error occurred while executing [@PostConstruct.]
javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is:
com.objectdb.o._PersistenceException: Object 'com.pingushare.entity.p1.User#2' belongs to another EntityManager
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:363)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:283)
at com.pingushare.control.TradesC$LocalBeanProxy.findTradeByClient(com/pingushare/control/TradesC.java)
at com.pingushare.boundary.dashboard.RequestsOngoingB.init(RequestsOngoingB.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.webbeans.intercept.InvocationContextImpl.proceedCommonAnnots(InvocationContextImpl.java:377)
at org.apache.webbeans.intercept.InvocationContextImpl.proceed(InvocationContextImpl.java:185)
at org.apache.webbeans.component.AbstractInjectionTargetBean.postConstructDefault(AbstractInjectionTargetBean.java:259)
at org.apache.webbeans.component.AbstractInjectionTargetBean.postConstruct(AbstractInjectionTargetBean.java:237)
at org.apache.webbeans.portable.creation.InjectionTargetProducer.postConstruct(InjectionTargetProducer.java:122)
at org.apache.webbeans.component.InjectionTargetWrapper.postConstruct(InjectionTargetWrapper.java:87)
at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:182)
at org.apache.webbeans.context.creational.BeanInstanceBag.create(BeanInstanceBag.java:81)
at org.apache.webbeans.context.AbstractContext.getInstance(AbstractContext.java:167)
at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:132)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:154)
at org.apache.webbeans.web.intercept.RequestScopedBeanInterceptorHandler.getContextualInstance(RequestScopedBeanInterceptorHandler.java:80)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:114)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:108)
at com.pingushare.boundary.dashboard.RequestsOngoingB_$$_javassist_63.getList(RequestsOngoingB_$$_javassist_63.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:64)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:58)
at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:179)
at org.apache.el.parser.AstValue.getValue(AstValue.java:183)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at org.apache.webbeans.el.WrappedValueExpression.getValue(WrappedValueExpression.java:68)
at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:96)
at javax.faces.component._DeltaStateHelper.eval(_DeltaStateHelper.java:249)
at org.apache.myfaces.view.facelets.component.UIRepeat.getValue(UIRepeat.java:242)
at org.apache.myfaces.view.facelets.component.UIRepeat.createDataModel(UIRepeat.java:193)
at org.apache.myfaces.view.facelets.component.UIRepeat.getDataModel(UIRepeat.java:185)
at org.apache.myfaces.view.facelets.component.UIRepeat._validateAttributes(UIRepeat.java:815)
at org.apache.myfaces.view.facelets.component.UIRepeat.process(UIRepeat.java:877)
at org.apache.myfaces.view.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1587)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:532)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:541)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:541)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:541)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1981)
at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:285)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
at org.ocpsoft.rewrite.faces.RewriteViewHandler.renderView(RewriteViewHandler.java:186)
at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:116)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:199)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:199)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.pingushare.boundary.filter.SecurityFilter.doFilter(SecurityFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: com.objectdb.o._PersistenceException: Object 'com.pingushare.entity.p1.User#2' belongs to another EntityManager
at com.objectdb.o._PersistenceException.b(_PersistenceException.java:45)
at com.objectdb.o.JPE.g(JPE.java:142)
at com.objectdb.o.ERR.f(ERR.java:60)
at com.objectdb.o.OBC.onObjectDBError(OBC.java:1484)
at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:695)
at com.pingushare.control.TradesC.findTradeByClient(TradesC.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.cdi.CdiInterceptor.invoke(CdiInterceptor.java:126)
at org.apache.openejb.cdi.CdiInterceptor.access$000(CdiInterceptor.java:42)
at org.apache.openejb.cdi.CdiInterceptor$1.call(CdiInterceptor.java:63)
at org.apache.openejb.cdi.CdiInterceptor.aroundInvoke(CdiInterceptor.java:69)
at sun.reflect.GeneratedMethodAccessor641.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:176)
at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:138)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:239)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:191)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:246)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:241)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:83)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:279)
... 76 more
Caused by: com.objectdb.o.UserException: Object 'com.pingushare.entity.p1.User#2' belongs to another EntityManager
at com.objectdb.o.MSG.d(MSG.java:61)
at com.objectdb.o.OBC.aE(OBC.java:586)
at com.objectdb.o.OBC.aD(OBC.java:571)
at com.objectdb.o.QRR.k(QRR.java:378)
at com.objectdb.o.QRR.j(QRR.java:347)
at com.objectdb.o.QRR.f(QRR.java:132)
at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:686)
... 107 more

The problem can be fixed by detaching User entity after query in #findUserById(Long id), but this shouldn't happen, at least in my understanding of how @Stateless transactional methods & transactional EM work.

Isn't that true?

Used application server: Apache Tomee 1.5.2

#4

The stack trace indeed indicates that a query parameter was rejected because it was associated with another EntityManager (i.e. not the EntityManager that is in use for running the query).

When an EntityManager is closed all its objects should be detached automatically (unless specified otherwise), so probably that EntityManager wasn't closed. The application server is allowed to reuse an EntityManager with stateless beans (and it is more efficient than using a new one for every method).

It would be very easy for ObjectDB to ignore this mismatch (we just have to comment a validity check), but the idea is to warn against mixing objects of different entity managers as soon as possible.

Accordingly, detaching the object before using it as a query parameter may be the right solution.

ObjectDB Support
#5

Ok. I understand. Thank you.

I reported it on Tomee's forum also, to see if that's what they expect.

Reply