Jboss 7.1.1 Transaction, cascade EJB methods

ejb-3.1, jboss7.x, transactions

Solution

You've left the most important part out; the JMS connection factory where you obtain the connection from and the way how you got hold of this factory.

Make sure you inject this factory, and that you use a transactional one. In JBoss AS 6, java:/JmsXA was the transactional one, and java:/ConnectionFactory the unmanaged/not-transactional alternative. Check that for AS 7 you are using the right one.

Problem

I have two stateless SessionBeans. My client (JSF2 application) is calling a method (saveOrderCompletion) on the first EJB (CompletionFacade), which calls another method (processRequest) on the second EJB (ContactFacade) to send a message to a queue via JMS. At the end of the first called method I am throwing a RuntimException to see how JBoss behaves. This should all run in one transaction, thus the transaction should do a rollback, so that no message should be sent to the queue. I double checked this this on weblogic server, which shows exactly the expeced behaviour. My question is why JBoss does not rollback the entire transaction? Did I miss something... The entity is not being persisted, but the message is sent to the queue anyway. I am using jboss 7.1.1, app is deployed as EAR Here are my session beans... ``` /** * Session Bean implementation class CompletionFacade */ @Stateless public class CompletionFacade implements CompletionFacadeRemote, CompletionFacadeLocal { @PersistenceContext(unitName="my_test") private EntityManager entityManager; @EJB ContactFacadeLocal contactFacade; ..... @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public OrderCompletion saveOrderCompletion(OrderCompletion orderCompletion) throws TestBusinessException { try { ...do some stuff on entity //persist to get id entityManager.persist(orderCompletion); //finally send email contactFacade.processRequest(orderCompletion,partner); if (0 == 0) throw new RuntimeException("Test RuntimeException "); } catch (TestGenericException re) { throw new TestBusinessException("Could not print orderCompletion: " ,re); } catch (DocumentException e) { throw new TestBusinessException("Could not print orderCompletion: " ,e); } return orderCompletion; } } ``` and the second facade: ``` @Stateless public class ContactFacade implements ContactFacadeRemote, ContactFacadeLocal { .... /* * actually create message */ @TransactionAttribute(TransactionAttributeType.REQUIRED) public void processRequest(Object request, SmtpPartner partner) throws TestGenericException { if (logger.isDebugEnabled()) { logger.debug("Starting to process request!"); } QueueConnection connection = null; QueueSession session = null; try { ...lookup queue etc... sender.send(QUEUE, objectMessage); } catch (JMSException e) { logger.error("MS Exception:", e); } catch (NamingException e) { logger.error("Naming exception:", e); } ... } finally { try { session.close(); connection.close(); } catch (JMSException e) { logger.error("Error closing connection:", e); } } } ... } ``` Any help is highly appreciated.

Original source