Hi all,

i'm very frustrated by Seam MDBs right now, here's my situation:

Having a MDB (on Queue) as Seam Component with an @In Stateless SessionBean. It 
gets called and executes a method within the SLSB.

My problem is: I need a new transaction at SLSB so the MDB shall mark the 
processed EntityBean on any error after Transaction is rolled back.

>From here my nightmare started:

#1 I tryied using:

  | @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  | 
on SLSBs method and let MDB onMessage unchanged 
--> doesn't work

#2 Using 

  | @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  | 
on both SLSB and MDBs onMessage:
--> doesn't work

#3 Using

  | @TransactionAttribute(TransactionAttributeType.REQUIRED)
  | 
on MDBs onMessage and REQUIRES_NEW at SLSB
--> doesn't work

I'm always getting following exception AFTER the MDBs onMessage has finished:

  | 15:55:16,921 WARN  [Component] Exception calling component @Destroy method: 
entityManager
  | java.lang.IllegalStateException: attempting to destroy the persistence 
context while an active transaction exists (try installing 
<transaction:ejb-transaction/>)
  |     at 
org.jboss.seam.persistence.ManagedPersistenceContext.close(ManagedPersistenceContext.java:216)
  |     at 
org.jboss.seam.persistence.ManagedPersistenceContext.destroy(ManagedPersistenceContext.java:179)
  |     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 org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
  |     at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:125)
  |     at org.jboss.seam.Component.callComponentMethod(Component.java:2083)
  |     at org.jboss.seam.Component.callDestroyMethod(Component.java:2014)
  |     at org.jboss.seam.Component.destroy(Component.java:1332)
  |     at org.jboss.seam.contexts.Contexts.destroy(Contexts.java:251)
  |     at 
org.jboss.seam.contexts.Contexts.flushAndDestroyContexts(Contexts.java:363)
  |     at org.jboss.seam.contexts.Lifecycle.endCall(Lifecycle.java:92)
  |     at 
org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:120)
  |     at 
org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
  |     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 
org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
  |     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.invokeInOurTx(TxPolicy.java:79)
  |     at 
org.jboss.aspects.tx.TxInterceptor$RequiresNew.invoke(TxInterceptor.java:262)
  |     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.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:245)
  |     at 
org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:268)
  |     at 
org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:138)
  |     at $Proxy142.onMessage(Unknown Source)
  |     at 
org.jboss.resource.adapter.jms.inflow.JmsServerSession.onMessage(JmsServerSession.java:178)
  |     at 
org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:891)
  |     at 
org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:170)
  |     at org.jboss.mq.SpySession.run(SpySession.java:323)
  |     at 
org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:237)
  |     at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
  |     at 
org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
  |     at 
EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
  |     at java.lang.Thread.run(Thread.java:595)
  | 

So I installed everything in components.xml:

  |     <core:init debug="@debug@" jndi-pattern="@jndiPattern@" 
transaction-management-enabled="true"/>
  | 
  |     <core:transactionListener />
  | 
  |     <transaction:ejb-transaction />
  | 

Still same. So I tracked down problem to ManagedPersistenceContext:

  |     private void close()
  |     {
  |         boolean transactionActive = false;
  |         try
  |         {
  |             transactionActive = Transaction.instance().isActive();
  |         }
  |         catch(SystemException se)
  |         {
  |             log.debug("could not get transaction status while destroying 
persistence context");
  |         }
  |         if(transactionActive)
  |             throw new IllegalStateException("attempting to destroy the 
persistence context while an active transaction exists (try installing 
<transaction:ejb-transaction/>)");
  |         if(log.isDebugEnabled())
  |             log.debug((new StringBuilder()).append("destroying seam managed 
persistence context for persistence unit: 
").append(persistenceUnitJndiName).toString());
  |         if(entityManager != null)
  |             entityManager.close();
  |     }
  | 
  | 

Then I discoverd the only way it works:

  |     @TransactionAttribute(TransactionAttributeType.NEVER)
  | 
at MDBs onMessage

BUT: This doesn't give me the chance to mark the entity without calling an 
other method annotated with REQUIRES_NEW

After testing, searching forum and web I've come to this by now:

JMS starts a transaction for the MDBs because if you want to publish to an 
other Queue, JMS must be sure your changes are commited before another message 
is been invoked.

When the SLSB is been destroyed, the EntityManager looks in 
Transaction.instance().isActive() and finds the open JMS Transaction so it 
refuses to destroy itself although its own transaction has been commited a 
while ago and is no more existing.

Is this a specified behavior?
Can I get around calling a second method to mark my EntityBean?
Or is this a bug? (I'll open JIRA then)

Thank you very much,

Greetz GHad

PS: Code is very basic and doesn't do any special, SLSB just gets an EntityBean 
by id, updates a field and returns. MDBs onMessage does nothing more than 
calling the SLSB.

Realted problem IMHO:
http://jboss.com/index.html?module=bb&op=viewtopic&t=117173


View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4085531#4085531

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4085531
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to