Search code examples
javahibernatejpatransactionsjta

NamingException: jta.UserTransaction


I have a hibernate application which directly uses Java Transaction API resources. I'm trying to use UserTransaction to accomplish some basic database transactions

The UserTransaction interface defines the methods that allow an application to explicitly manage transaction boundaries

In hibernate.cfg.xml file I have the following properties:

<session-factory>
    <property name="show_sql">true</property>
    <property name="connection.datasource">java:comp/env/myDataSource</property>
    <property name="jta.UserTransaction">java:comp/UserTransaction</property>
    <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>

In the web.xml of the app, UserTransaction is set in the <resource-env-ref>

<resource-env-ref>
    <description>Object factory for MyBean instances.</description>
    <resource-env-ref-name>UserTransaction</resource-env-ref-name>
    <resource-env-ref-type>javax.transaction.UserTransaction</resource-env-ref-type>
</resource-env-ref>

And in the code, I try to lookup the UserTransaction with InitialContext by its JNDI name

public UserTransaction getTransactionContext()
    throws Exception
    {
        if (this.ut == null) {
            ut = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction");
        }
    return ut;
    }   

However the following exception gets returned:

03:27:37,530 ERROR [someServlet:555] Error in someMethod
javax.naming.NamingException: Cannot create resource instance
    at org.apache.naming.factory.ResourceEnvFactory.getObjectInstance(ResourceEnvFactory.java:117)
    at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:843)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
    at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)

This application was ported over from a Weblogic server where it was functioning noramlly to Apache Tomcat; That being said - do I need to define UserTransaction in my context.xml in order for getTransactionContext() to locate it? If not, how can I appropriately return the UserTransaction within my code?


Solution

  • Porting an application from a full-blown Java EE application server to Tomcat (web application server) requires some extra steps.

    All Java EE servers come with a JTA transaction manager and their transaction engine manages transaction binding and transaction resolving, like the UserTransaction JNDI context.

    You can use Bitronix or Atomikos, and you need to set both the UserTransaction and the TransactionSyncronizationRegistry in Tomcat context.xml.