0 Replies Latest reply on Oct 16, 2012 7:40 AM by amitsoprna

    Transactions are not working as expected after migrating to JBOSS7.1 from JBOSS4.2

    amitsoprna

      Hi JBOSS Gurus,

       

      I am facing a problem while migrating from JBOSS 4.2 to 7.1

       

      Our application is using Entity EJBS 3.0, JPA, Hibernate 3.

       

      Following was our earlier persistence.xml

       

      <persistence>

          <persistence-unit name="my_application-core" transaction-type="RESOURCE_LOCAL">

              <provider>org.hibernate.ejb.HibernatePersistence</provider>

              <non-jta-data-source>java:/MyApplicationDS</non-jta-data-source>

              <properties>

                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

                  <property name="hibernate.cache.use_query_cache" value="false" />

                  <property name="hibernate.show_sql" value="false" />

                  <property name="jboss.entity.manager.jndi.name" value="java:/EntityManagers/my_application-core" />

                  <property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagers/my_application-core-factory" />

                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

                  <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />

                  <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />

                  <property name="hibernate.transaction.flush_before_completion" value="true" />

                  <property name="hibernate.connection.release_mode" value="auto" />

              </properties>

          </persistence-unit>

      </persistence>

       

      And following was the Datasource

       

      <datasources>

          <local-tx-datasource>

              <jndi-name>MyApplicationDS</jndi-name>

              <connection-url>jdbc:mysql://localhost:3306/mydatabase?characterEncoding=UTF-8</connection-url>

              <driver-class>com.mysql.jdbc.Driver</driver-class>

              <user-name>root</user-name>

              <password></password>

              <max-pool-size>50</max-pool-size>

              <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>

              <new-connection-sql>select 1</new-connection-sql>

              <check-valid-connection-sql>select 1</check-valid-connection-sql>

              <metadata>

                  <type-mapping>mySQL</type-mapping>

              </metadata>

          </local-tx-datasource>

      <datasources>

       

      And following java code where we do more than one save or update one after the other and all of them are in thie separate transactions:

       

                 TransactionUtil trx = (TransactionUtil) baseFactory.getInstance(TransactionUtil.class);

                  trx.beginTransaction();

                  xyzManager.saveXYZ(...);

                  trx.commitTransaction();

       

       

                  TransactionUtil trx = (TransactionUtil) baseFactory.getInstance(TransactionUtil.class);

                  trx.beginTransaction();

                  abcManager.saveABC(...);

                  trx.commitTransaction();

       

      Code for begin transaction and commit transaction is as follows:

       

      public static EntityTransaction beginTransaction() throws MyOrgException {

              EntityManager em=getEntityManager(System.getProperty(PERSISTENCE_UNIT_KEY));

              EntityTransaction transaction = null;

       

              if(em.isOpen())

              {

                  transaction = em.getTransaction();

                  if(!transaction.isActive())

                  {   

                      transaction.begin();

                  }

                  else

                  {

                      log.debug("EntityManager transaction (" +

                          transaction.hashCode() + ") was active for thread (" + Thread.currentThread().hashCode() + ").");

                  }

              }

              else

              {

                  throw new MyOrgException("EntityManager for thread (" +

                      Thread.currentThread().hashCode() + ") is already closed");

              }       

              return transaction;

      }

       

      public static void commitTransaction() throws MyOrgException{

              EntityManager em=(EntityManager)emCol.get();

       

              if (em == null) {

                  log.warn("No entity manager had been created for this thread (" +

                      Thread.currentThread().hashCode() + "). Cannot commit transaction.");

              }

              else if(em.isOpen())

              {

                  EntityTransaction transaction = em.getTransaction();

                  if(transaction.isActive())

                  {   

                      log.debug("EntityManager for thread (" +

                          Thread.currentThread().hashCode() + ") has active transaction (" +

                          transaction.hashCode() + "): commit");

                      transaction.commit();

                  }

                  else

                  {

                      throw new MyOrgException("EntityManager transaction (" +

                          transaction.hashCode() + ") is not active for thread (" + Thread.currentThread().hashCode() + ")");

                  }

              }

              else

              {

                  throw new MyOrgException("EntityManager for thread (" +

                      Thread.currentThread().hashCode() + ") is already closed");

              }

          }

       

      which used to work perfectly on JBOSS 4.2.

       

       

      But the same code deployed to JBOSS7.1 throws exception on second trx.beginTransaction(); call saying "transaction is in invalid state".

       

      I noticed while debuggin that the UserTransaction set in the EntityTransaction has a flag valid which is set to false after the first commit. And hence on the second begin call it fails with the above mentioned exception.

       

      What should be the correct settings on JBOSS7.1 for the above scenarios as I am getting the following errors or warnings while trying various combinations:

       

      My DataSource on JBOSS7.1 is as follows:

       

                     <datasource jta="false" jndi-name="java:/MyApplicationDS" pool-name="MyApplicationDS" enabled="true" use-java-context="true">

                          <connection-url>jdbc:mysql://localhost:3306/mydatabase?useOldAliasMetadataBehavior=true&amp;characterEncoding=UTF-8</connection-url>

                          <driver-class>com.mysql.jdbc.Driver</driver-class>

                          <driver>mysql</driver>

                          <new-connection-sql>select 1</new-connection-sql>

                          <pool>

                              <max-pool-size>50</max-pool-size>

                          </pool>

                          <security>

                              <user-name>root</user-name>

                          </security>

                          <validation>

                              <check-valid-connection-sql>select 1</check-valid-connection-sql>

                              <exception-sorter class-name="org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter"/>

                          </validation>

                      </datasource>

       

      And I have tried following combinations in the persistence.xml with the given results:

       

      (1)

       

      When none of the JTA related settings are given then :

       

      Following warning comes up

       

      02:51:50,346 WARN  [org.hibernate.internal.SessionFactoryImpl] (MSC service thread 1-3) HHH000008: JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()

       

      And at the places where we are doing an insert or update without enclosing them between the beginTransaction() and closeTransaction() calls following error is thrown

       

      Caused by: com.myorg.shared.util.MyOrgException: Error getting Entities for the entityid: 10

              at com.myorg.builder.MyEntityBuilderImpl.getMyEntity(MyEntityBuilderImpl.java:177) [myorg.jar:]

              at com.myorg.buslog.MyEntityBLImpl.getMyEntity(MyEntityBLImpl.java:186) [myorg.jar:]

              ... 92 more

      Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query

              at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at com.myorg.builder.MyEntityBuilderImpl.getMyEntity(MyEntityBuilderImpl.java:118) [myorg.jar:]

              ... 93 more

       

      (2)

       

      When the following setting is given then :

       

      <property name="hibernate.transaction.factory_class" value="org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory" />

       

      which is a replacement of earlier

       

      <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />

       

      property to get rid of the warning mentioned aboe then the following warning comes up

       

      02:58:28,606 WARN  [org.hibernate.ejb.Ejb3Configuration] (MSC service thread 1-1) HHH000193: Overriding hibernate.transaction.factory_class is dangerous, this might break the EJB3 specification implementation

       

      And at the places where we are doing an insert or update following exception is thrown

       

      Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: Unable to locate JTA UserTransaction

              at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1371) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:60) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at com.myorg.builder.util.EntityManagerUtil.beginTransaction(EntityManagerUtil.java:303) [myorg.jar:]

              at com.myorg.builder.util.TransactionUtilImpl.beginTransaction(TransactionUtilImpl.java:33) [myorg.jar:]

              ... 70 more

      Caused by: org.hibernate.TransactionException: Unable to locate JTA UserTransaction

              at org.hibernate.engine.transaction.internal.jta.JtaTransaction.doBegin(JtaTransaction.java:73) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1263) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:57) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

       

      (3)

       

      When the following setting is given

       

      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />

       

      which is to replace the following settings that we used to give earlier:

       

      <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />

      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />

       

       

      then the following warning comes:

       

      [org.hibernate.internal.SessionFactoryImpl] (MSC service thread 1-5) HHH000008: JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()

       

      and

       

      And at the places where we are doing an insert or update following exception is thrown

       

      Caused by: com.myorg.shared.util.MyOrgException: Error getting Entities for the entityid: 10

              at com.myorg.builder.MyEntityBuilderImpl.getMyEntity(MyEntityBuilderImpl.java:177) [myorg.jar:]

              at com.myorg.buslog.MyEntityBLImpl.getMyEntity(MyEntityBLImpl.java:186) [myorg.jar:]

              ... 92 more

      Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query

              at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at com.myorg.builder.MyEntityBuilderImpl.getMyEntity(MyEntityBuilderImpl.java:118) [myorg.jar:]

              ... 93 more

       

      (4)

       

      When the following setting are given then :

       

      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />

      <property name="hibernate.transaction.factory_class" value="org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory" />

       

      which is a replacement of earlier

       

      <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />

       

      property to get rid of the warning mentioned aboe then the following warning comes up

       

      [org.hibernate.ejb.Ejb3Configuration] (MSC service thread 1-2) HHH000193: Overriding hibernate.transaction.factory_class is dangerous, this might break the EJB3 specification implementation.

       

      And the following exception occurs

       

      Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: Transaction instance is no longer valid

              at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1371) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:60) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              at com.myorg.builder.util.EntityManagerUtil.beginTransaction(EntityManagerUtil.java:303) [myorg.jar:]

              at com.myorg.builder.util.TransactionUtilImpl.beginTransaction(TransactionUtilImpl.java:33) [myorg.jar:]

              ... 70 more

      Caused by: org.hibernate.TransactionException: Transaction instance is no longer valid

              at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:149) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1263) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]

              at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:57) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

              ... 73 more

       

      on the second transaction begin method call in the code where we have code of type as given below:

       

       

                  TransactionUtil trx = (TransactionUtil) baseFactory.getInstance(TransactionUtil.class);

                  trx.beginTransaction();

                  xyzManager.saveXYZ(...);

                  trx.commitTransaction();

       

       

                  TransactionUtil trx = (TransactionUtil) baseFactory.getInstance(TransactionUtil.class);

                  trx.beginTransaction();

                  abcManager.saveABC(...);

                  trx.commitTransaction();

       

      So when a call to begin transaction goes for the second time in the same reuest or code flow the application bombs with the above error.

       

      And this is the same error that we get with the original persistence.xml settings which are:

       

      <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />

      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />

      <property name="hibernate.transaction.flush_before_completion" value="true" />

       

      I tried using Hibernate3 with JBOSS7.1 as well but that didn't woked either.

       

      Can anyone please help me out of this, thanks a lot in advance.

       

      Please feel free to ask any other information if you think that would help in understanding the problem.