You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat下Spring5+Hibernate5+Atomikos4整合:JTA事务定位失败问题

Fixing "Unable to locate current JTA transaction" with Spring 5, Hibernate 5 and Atomikos on Tomcat

I’ve been down this road before with Spring + Hibernate + Atomikos on Tomcat— that org.hibernate.HibernateException: Unable to locate current JTA transaction error is no fun. Let’s walk through what’s off in your setup and get it fixed.

First, let’s break down the key issues I spot in your config and code:

  1. Your LocalSessionFactoryBean has conflicting properties that are throwing Hibernate off when trying to find the JTA transaction
  2. The static fields in your SpringJtaPlatformAdapter can cause lifecycle issues with Spring’s bean initialization
  3. There’s a missing piece in linking Spring’s transaction management to Hibernate’s JTA context

Let’s fix each part step by step:

Step 1: Clean Up the SessionFactory Configuration

Your current LocalSessionFactoryBean has properties that should be handled by Atomikos, not Hibernate directly. Let’s trim those out and set the correct JTA properties:

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    <property name="hibernateProperties">
        <props>
            <!-- Keep your cache settings as-is -->
            <prop key="hibernate.cache.use_query_cache">true</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
            <prop key="net.sf.ehcache.configurationResourceName">/ehcache/ehcache.xml</prop>
            
            <!-- Critical JTA settings - these tell Hibernate to use Spring/Atomikos transactions -->
            <prop key="hibernate.transaction.jta.platform">cgaweb.common.atomikos.SpringJtaPlatformAdapter</prop>
            <prop key="hibernate.current_session_context_class">jta</prop>
            <prop key="javax.persistence.transactionType">JTA</prop>
            
            <!-- Database and other core settings -->
            <prop key="hibernate.max_fetch_depth">2</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.id.new_generator_mappings">true</prop>
            <prop key="hibernate.mapping.precedence">class, hbm</prop>
        </props>
    </property>
    <!-- Remove the hibernate.connection.datasource property here - Atomikos manages this via JNDI -->
</bean>

What changed:

  • Removed hibernate.connection.datasource, hibernate.connection.autocommit, hibernate.connection.release_mode, and connection.driver_class— these are all managed by Atomikos for JTA, so Hibernate doesn’t need to handle them
  • Fixed javax.persistence.transactionType to be uppercase JTA (some implementations are case-sensitive here)

Step 2: Fix the SpringJtaPlatformAdapter

Using static fields in this adapter is risky because Hibernate might try to access them before Spring has finished initializing the bean. Let’s switch to instance fields and use Spring’s autowiring properly:

public class SpringJtaPlatformAdapter extends AbstractJtaPlatform {
    private TransactionManager transactionManager;
    private UserTransaction userTransaction;

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

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

    @Autowired
    public void setJtaTransactionManager(JtaTransactionManager jtaTransactionManager) {
        this.transactionManager = jtaTransactionManager.getTransactionManager();
        this.userTransaction = jtaTransactionManager.getUserTransaction();
    }
}

Key fixes:

  • Got rid of static fields— now each bean instance holds its own references, which plays nice with Spring’s lifecycle
  • Added @Autowired to the setter so Spring automatically injects the JtaTransactionManager when initializing the adapter
  • Removed redundant setters since we’re pulling everything from the JtaTransactionManager

Step 3: Enable Transaction Management in Spring

You need to tell Spring to handle transaction annotations. If you’re using XML config, add this to your application-context.xml (don’t forget the tx namespace in the header):

First, add the namespace to the root bean element:

xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"

Then add the annotation-driven transaction management:

<tx:annotation-driven transaction-manager="transactionManager"/>

If you’re using Java config instead, just add @EnableTransactionManagement to your configuration class.

This ensures that when you annotate your service methods with @Transactional, Spring starts a JTA transaction that Hibernate can pick up.

Step 4: Verify Tomcat JNDI Datasource Setup

Since you’re using java:/comp/env/jdbc/myoracle, make sure your Tomcat context.xml has the Atomikos-managed XA datasource configured correctly. Here’s an example:

<Resource name="jdbc/myoracle" 
          auth="Container"
          type="com.atomikos.jdbc.AtomikosDataSourceBean"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          uniqueResourceName="myoracle"
          xaDataSourceClassName="oracle.jdbc.xa.client.OracleXADataSource"
          xaProperties.URL="jdbc:oracle:thin:@//your-db-host:1521/your-sid"
          xaProperties.user="your-db-user"
          xaProperties.password="your-db-password"
          maxPoolSize="20"
          minPoolSize="5"/>

This ensures the datasource is properly registered with Atomikos for JTA transaction management.

Quick Final Checks

  • Double-check your dependencies: you’ll need transactions-hibernate5-4.0.4.jar (not just transactions-jta-4.0.4.jar) to get Atomikos working with Hibernate 5
  • Make sure your service methods are annotated with @Transactional— without this, Spring won’t start a transaction for Hibernate to find
  • Ensure your hibernate.cfg.xml doesn’t override any of the JTA settings we configured in Spring

After making these changes, Hibernate should correctly locate the active JTA transaction managed by Spring and Atomikos, and that error should disappear.

内容的提问来源于stack exchange,提问作者Loic Kouam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:35:57