Home > Java > How to use Bean Managed Transactions with EJB3, JPA and JTA

How to use Bean Managed Transactions with EJB3, JPA and JTA

During a “little” project I am doing in my spare time, I found out that switching to Bean Managed Transactions (BMT) wasn’t as easy as I expected. When you’ve used Container Managed Transactions (CMT) and are switching to BMT with JTA like I was, you need to know the following:

First of all the persistence unit needs to define a <jta-data-source> and not a <non-jta-data-source>

<persistence-unit name=”TopLinkPU”>
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<jta-data-source>jdbc/gpslocationsharing</jta-data-source>
</persistence-unit>

Because you are using JTA you can’t fetch a new EntityTransaction from the entity manager. You’ll have to get a UserTransaction from the EJBContext. To do this, have the EJB container inject the EJBContext using the following code:

@Resource
private EJBContext context;

After the container has injected the EJBContext you can simply start, use and commit a transaction like this:

UserTransaction tx = context.getUserTransaction();
tx.begin();
em.persist(client);
tx.commit();

Knowing the above, using BMT with EJB3, JTA and JPA is really easy! The point is to find the right information. And now you have!

Enjoy!

Categories: Java Tags: , , ,
  1. Vivek
    January 4, 2009 at 12:10 pm

    After following the above steps I am still getting the following exception:

    java.lang.IllegalStateException: Container AddStationBean: it is illegal to inject UserTransaction into a CMT bean
    16:12:44,382 ERROR [STDERR] at org.jboss.ejb3.BaseSessionContext.getUserTransaction(BaseSessionContext.java:248)
    16:12:44,382 ERROR [STDERR] at com.avaya.iptcm.cm.ui.station.AddStationBean.addStationTemplateAssociation(AddStationBean.java:733)
    16:12:44,382 ERROR [STDERR] at com.avaya.iptcm.cm.ui.station.AddStationBean.addStation(AddStationBean.java:705)

  2. January 5, 2009 at 9:37 am

    The exception says you’re still using a Container Managed Transaction bean. Switching to a BMT bean is something i didn’t mention in the article, just the problems that occur after that.

    You forgot to change the transaction type of the bean to BMT.

  3. elvisd79
    January 20, 2009 at 5:50 pm

    Hi Geert,

    sorry but I’m starting with EJB3 development, and translations.
    Transaction is BMT.
    For every Entity (POJO) I have a Dao (Common CRUD operations in an extended abstract class) as stateless SB (transactionmanager set to BMT).
    From a client (Eclipse RCP/RAP) I have to manage a transaction, to accomplish this I have a Statefull SB to begin/commit/rollback a transaction (injected usertransaction).

    From the client I do:

    SFSB.begin();
    Entity e = new Entity(param1,param2);
    SLDao.save(e); // throws an Exception:
    /*
    Persisting object: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction
    */

    in the save method I do:

    em.joinTransaction(); // em is injected EntityManager –> here throws exception!
    em.persist(e);

    Have you any Idea?
    Have you any complex client – server transactions example?
    Thank you.

    Kindly

    elvisd79

    • January 21, 2009 at 12:54 pm

      Hey Elvis,

      The fact that the exception is thrown means that your “statefull SB to begin/commit/rollback” didn’t start a transaction. Try testing the DAO with a Unit test in which you manually start a transaction and call the DAO.

  4. Marius
    May 1, 2009 at 9:50 am

    Hello Geert,

    I apologize I’m a little off topic but this is a problem that’s been bothering me for some time now. If I use JTA transaction how can I handle the exceptions? Especially the ones related to breaking constraints in the database. Small example:

    java.lang.RuntimeException: javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Can’t commit because the transaction is in aborted state
    .. there are some additional Caused by .. to eventually get to the last Caused by:
    Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

    If I try to catch javax.transaction.RollbackException along with a general Exception the error will be caught by the general Exception block and not RollbackException.

    Maybe you can give me some hints.

    Thanks,
    Marius

  5. Yann
    May 29, 2013 at 10:24 pm

    Clarifying this point (for beginners):

    @TransactionManagement:
    specifies if CMT or BMT is used for a particular bean, the default is CMT, the options are

    •TransactionManagementType.CONTAINER
    •TransactionManagementType.BEAN

  1. No trackbacks yet.

Leave a comment