Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Atomikos Transaction Essentials with Hibernate >= 4.3

I switched from Hibernate 4.2 to Hibernate 4.3 and my project is not working any more. I'm getting an

HibernateException: Unable to locate current JTA transaction

when I do

Session s = sessionFactory.getCurrentSession();

I've realized that org.hibernate.transaction.TransactionManagerLookup does not exist any more. It was deleted in Hibernate 4.3. How should I change my current configuration?

<hibernate-configuration>
<session-factory>
    <property name="connection.datasource">testDS</property>

    <property name="current_session_context_class">jta</property>
    <property name="transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</property>
    <property name="transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
    <property name="connection.release_mode">auto</property>
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

    <property name="hibernate.hbm2ddl.auto">create-drop</property>
    <property name="hibernate.show_sql">true</property>
    <mapping class="test.entities.Person" />
    <mapping class="test.entities.CreditCard" />
    <mapping class="test.entities.ExampleRevEntity" />
</session-factory>

like image 256
sebplorenz Avatar asked Dec 19 '13 11:12

sebplorenz


People also ask

Does atomikos support hibernate?

Atomikos has great support for several JPA implementations, including Hibernate. As before, our application remains agnostic to Atomikos as well as Hibernate, thanks to Spring and JPA! Let's see how Spring, JPA, and Hibernate can make our application even more concise while providing the benefits of distributed transactions through Atomikos.

How are the atomikosusertransaction and atomikostransactionmanager constructed?

the atomikosUserTransaction and atomikosTransactionManager of Atomikos are constructed first the setJtaTransactionManager method of my SpringJtaPlatformAdapter is called, both memory addresses for the sTransactionManager and sUserTransaction are consistent with the ones created before

What are transactions in atomikos?

Before we discuss Atomikos, let's understand what exactly transactions are and a few concepts related to them. Put simply, a transaction is a logical unit of work whose effect is visible outside the transaction either in entirety or not at all. Let's take an example to understand this better.

Does atomikos prohibit us from using a single data source?

Atomikos does not prohibit us from using such a data source and still try to provide atomicity if there is a single such data source in the transaction. This technique is similar to Last Resource Gambit, a variation of the two-phase commit process. Further, we need to appropriately configure the DataSource depending upon the database and driver.


2 Answers

In Hibernate 4.3 the long deprecated TransactionManagerLookup got removed. Now the JTA provider must implement org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform. An abstract implementation of JTA Platform is already available within Hibernate namely org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform. Using this it is quite simple to write a JTA Platform for Atomikos:

package test;

import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform;
import com.atomikos.icatch.jta.UserTransactionManager;

public class AtomikosJtaPlatform extends AbstractJtaPlatform {

  private static final long serialVersionUID = 1L;
  private UserTransactionManager utm;

  public AtomikosJtaPlatform() {
    utm = new UserTransactionManager();
  }

  @Override
  protected TransactionManager locateTransactionManager() {
    return utm;
  }

  @Override
  protected UserTransaction locateUserTransaction() {
    return utm;
  }
}

In addition the name of the platform implementation class must be added to the hibernate configuration:

<property name="hibernate.transaction.jta.platform">test.AtomikosJtaPlatform</property>
like image 91
sebplorenz Avatar answered Oct 20 '22 08:10

sebplorenz


To use Hibernate JTA Platform with Spring write and compile this code

package my.domain.spring.hibernate.jta;

import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.util.Assert;

@SuppressWarnings("serial")
public class SpringJtaPlatformAdapter extends AbstractJtaPlatform {

    private static TransactionManager sTransactionManager;
    private static UserTransaction sUserTransaction;


    @Override
    protected TransactionManager locateTransactionManager() {
        Assert.notNull(sTransactionManager, "TransactionManager has not been setted");
        return sTransactionManager;
    }


    @Override
    protected UserTransaction locateUserTransaction() {
        Assert.notNull(sUserTransaction, "UserTransaction has not been setted");
        return sUserTransaction;
    }


    public void setJtaTransactionManager(JtaTransactionManager jtaTransactionManager) {
        sTransactionManager = jtaTransactionManager.getTransactionManager();
        sUserTransaction = jtaTransactionManager.getUserTransaction();
    }


    public void setTransactionManager(TransactionManager transactionManager) {
        sTransactionManager = transactionManager;
    }


    public void setUserTransaction(UserTransaction userTransaction) {
        sUserTransaction = userTransaction;
    }

}

Add into your spring-configuration

  <bean id="txObjcoreManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager">
            <bean class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
                <property name="forceShutdown" value="true" />
            </bean>
        </property>
        <property name="userTransaction">
            <bean class="com.atomikos.icatch.jta.UserTransactionImp">
                <property name="transactionTimeout" value="300" />
            </bean>
        </property>
    </bean>

    <bean id="springJtaPlatformAdapter" class="my.domain.spring.hibernate.jta.SpringJtaPlatformAdapter">
        <property name="jtaTransactionManager" ref="txObjcoreManager" />
    </bean>

Don't forget to add a dependency

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        depends-on="springJtaPlatformAdapter">

And finally change a hibernate configuration like this one hibernate.transaction.jta.platform=my.domain.spring.hibernate.jta.SpringJtaPlatformAdapter

like image 27
Anton Lem Avatar answered Oct 20 '22 07:10

Anton Lem