2 Replies Latest reply on Apr 5, 2006 6:38 AM by clairecostello

    Failure when committing JTA transaction: status=STATUS_NO_TR

    sprhodes

      Hi all, having a little problem that I'm hoping someone can shed some light on.

      I have a servlet in which I'm trying to use JTA transactions, but when I call the commit() method on the UserTransaction, I get back:


      2006-01-03 21:08:25,718 INFO [STDOUT] org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=pathfinder/16, BranchQual=, localId=16] status=STATUS_NO_TRANSACTION

      2006-01-03 21:08:25,718 INFO [STDOUT] at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:344)
      2006-01-03 21:08:25,718 INFO [STDOUT] at org.jboss.tm.TxManager.commit(TxManager.java:200)
      2006-01-03 21:08:25,718 INFO [STDOUT] at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:126)
      2006-01-03 21:08:25,718 INFO [STDOUT] at test.TransactServlet.doGet(TransactServlet.java:52)



      I added some debugging statements to check though, and there is an active transaction right at the moment when commit() is called. This we can see from a slightly larger snippet of the trace file:


      2006-01-03 21:08:25,687 INFO [test.TransactServlet] Before commit: 0 - STATUS_ACTIVE

      2006-01-03 21:08:25,687 DEBUG [org.hibernate.transaction.CacheSynchronization] transaction before completion callback
      2006-01-03 21:08:25,687 DEBUG [org.hibernate.transaction.CacheSynchronization] automatically flushing session
      2006-01-03 21:08:25,687 DEBUG [org.hibernate.impl.SessionImpl] automatically flushing session
      2006-01-03 21:08:25,687 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] flushing session
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushing entities and processing referenced collections
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Processing unreferenced collections
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Scheduling collection removes/(re)creates/updates
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 0 updates, 0 deletions to 1 objects
      2006-01-03 21:08:25,703 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.pretty.Printer] listing entities:
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.pretty.Printer] test.UserObject{name=JBossHibernate, id=77}
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] executing flush
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] post flush
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.jdbc.JDBCContext] before transaction completion
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.impl.SessionImpl] before transaction completion
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.transaction.CacheSynchronization] transaction after completion callback, status: 4
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.jdbc.JDBCContext] after transaction completion
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.impl.SessionImpl] after transaction completion
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.jdbc.JDBCContext] no active transaction, could not register Synchronization
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.jdbc.JDBCContext] no active transaction, could not register Synchronization
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.transaction.CacheSynchronization] automatically closing session
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.impl.SessionImpl] automatically closing session
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.impl.SessionImpl] closing session
      2006-01-03 21:08:25,718 DEBUG [org.hibernate.jdbc.ConnectionManager] connection already null in cleanup : no action
      2006-01-03 21:08:25,718 INFO [STDOUT] org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=pathfinder/16, BranchQual=, localId=16] status=STATUS_NO_TRANSACTION
      2006-01-03 21:08:25,718 INFO [STDOUT] at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:344)
      2006-01-03 21:08:25,718 INFO [STDOUT] at org.jboss.tm.TxManager.commit(TxManager.java:200)
      2006-01-03 21:08:25,718 INFO [STDOUT] at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:126)
      2006-01-03 21:08:25,718 INFO [STDOUT] at test.TransactServlet.doGet(TransactServlet.java:52)

      Here is the code for the servlet in question:

       @Override
       protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
       {
       try
       {
       /* get JNDI Context */
       InitialContext jndiCtx = new InitialContext();
      
       SessionFactory sf =
       new Configuration().configure().buildSessionFactory();
      
       // get the UserTransactionObject
       UserTransaction ut = (UserTransaction)jndiCtx.lookup( "UserTransaction" );
      
       ut.begin();
       logger.info( "UT status right after begin: " + getStatusName( ut.getStatus() ) );
      
       // and open the Hibernate session
       Session session = sf.getCurrentSession();
      
       // do something transactional using Hibernate
       UserObject obj = new UserObject( "JBossHibernate" );
       session.save( obj );
      
       // do something else involving the transaction (send a JMS message, for example)
       // TODO: add a separate transactional step here
      
       logger.info( "Before commit: " + getStatusName( ut.getStatus() ) );
      
      
      
       // commit the transaction
      /* this is where it blows up!! */
       ut.commit();
      
       logger.info( "After commit: " + getStatusName( ut.getStatus() ) );
      
       PrintWriter out = response.getWriter();
       out.append( "<html><head><title>Success</title></head><body><p />Success!</body>");
       }
       catch( Exception e )
       {
       e.printStackTrace();
      
       PrintWriter out = response.getWriter();
      
       StringWriter sw = new StringWriter();
       PrintWriter pw = new PrintWriter(sw, true);
       pw.append( "<html><head><title>Error</title></head><body><p />" );
       e.printStackTrace(pw);
       pw.append( "</body>");
      
       pw.flush();
       sw.flush();
      
       out.print( sw.toString() );
       }
      



      If it helps, here are the datasource definition and the hibernate.cfg.xml:

      datasource

      <?xml version="1.0" encoding="UTF-8"?>
      
      <!-- ===================================================================== -->
      <!-- -->
      <!-- JBoss Server Configuration -->
      <!-- Thanks to Horia Muntean <horia@bvb.ro> -->
      <!-- ===================================================================== -->
      
      <!-- $Id: db2-xa-ds.xml,v 1.4 2004/09/15 14:37:40 loubyansky Exp $ -->
      
      
      <datasources>
       <!--
       XADatasource for DB2 V8.1 (app driver)
       copy $db2_install_dir/java/db2java.zip into $jboss_install_dir/server/default/lib
       -->
      
       <xa-datasource>
       <jndi-name>db2DataSource</jndi-name>
      
       <xa-datasource-class>COM.ibm.db2.jdbc.DB2XADataSource</xa-datasource-class>
       <xa-datasource-property name="DatabaseName">HIBTEST</xa-datasource-property>
       <xa-datasource-property name="User">prhodes</xa-datasource-property>
       <xa-datasource-property name="Password">redacted</xa-datasource-property>
      
       <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
       <metadata>
       <type-mapping>DB2</type-mapping>
       </metadata>
       </xa-datasource>
      
      </datasources>
      
      


      hibernate config


      <hibernate-configuration>
       <session-factory>
       <property name="connection.autocommit">false</property>
       <property name="connection.datasource">java:/db2DataSource</property>
       <property name="dialect">org.hibernate.dialect.DB2Dialect</property>
       <property name="transaction.flush_before_completion">true</property>
       <property name="transaction.auto_close_session">true</property>
       <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
       <property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
       <property name="current_session_context_class">jta</property>
      
       <mapping resource="test/UserObject.hbm.xml" />
      
       </session-factory>
      
      </hibernate-configuration>
      
      


      UserObject is just a stupid little class with an id and one attribute:

      <hibernate-mapping>
       <class name="test.UserObject" table="USEROBJECT">
       <id name="id" column="ID" type="long">
       <generator class="native" />
       </id>
       <property name="name" column="NAME" type="string" />
       </class>
      </hibernate-mapping>
      


      package test;
      
      public class UserObject
      {
       private Long id;
       private String name;
      
       public UserObject()
       {
       }
      
       public UserObject( String name )
       {
       this.name = name;
       }
      
       public Long getId()
       {
       return id;
       }
      
       public void setId( Long id )
       {
       if( this.id == null )
       {
       this.id = id;
       }
       else
       {
       throw new RuntimeException( "attempt to modify immutable field \"id\" with value: " + this.id );
       }
       }
      
       public void setName( String name )
       {
       this.name = name;
       }
      
       public String getName()
       {
       return name;
       }
      }