hibernate/hibernate-orm · error · HibernateException

DdlTransactionIsolatorJtaImpl could not locate TransactionMa

Error message

DdlTransactionIsolatorJtaImpl could not locate TransactionManager to suspend any current transaction; base JtaPlatform impl (${jtaPlatform})?

What it means

HibernateException from DdlTransactionIsolatorJtaImpl: to run DDL isolated from the current JTA transaction Hibernate must suspend that transaction, but the configured JtaPlatform's retrieveTransactionManager() returned null — there is no TransactionManager to suspend with. The JtaPlatform in effect is wrong or is a stub that cannot supply a TM (the message even names the impl found).

Source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java:42

 */
public class DdlTransactionIsolatorJtaImpl implements DdlTransactionIsolator {
	private final JdbcContext jdbcContext;

	private final Transaction suspendedTransaction;
	private Connection jdbcConnection;

	private static JtaPlatform getJtaPlatform(JdbcContext jdbcContext) {
		return jdbcContext.getServiceRegistry().requireService( JtaPlatform.class );
	}

	public DdlTransactionIsolatorJtaImpl(JdbcContext jdbcContext) {
		this.jdbcContext = jdbcContext;

		try {
			final var jtaPlatform = getJtaPlatform( jdbcContext );
			final var transactionManager = jtaPlatform.retrieveTransactionManager();
			if ( transactionManager == null ) {
				throw new HibernateException(
						"DdlTransactionIsolatorJtaImpl could not locate TransactionManager to suspend any current transaction; " +
						"base JtaPlatform impl (" + jtaPlatform + ")?"
				);
			}
			suspendedTransaction = transactionManager.suspend();
			JTA_LOGGER.suspendedTransactionForDdlIsolation( suspendedTransaction );
		}
		catch (SystemException e) {
			throw new HibernateException( "Unable to suspend current JTA transaction in preparation for DDL execution" );
		}

	}

	@Override
	public JdbcContext getJdbcContext() {
		return jdbcContext;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Configure a JtaPlatform that actually exposes the TransactionManager for your runtime (e.g. JBossAppServerJtaPlatform on WildFly, or a Narayana/Atomikos-aware implementation for embedded use)
  2. If you implement JtaPlatform yourself, return a real TransactionManager from retrieveTransactionManager()
  3. Move DDL out of the JTA boot path: run Flyway/Liquibase before Hibernate starts and set hbm2ddl.auto to validate or none
  4. As a stopgap, run the schema-update phase with a resource-local configuration

Example fix

// before
props.put("hibernate.transaction.jta.platform", MyStubJtaPlatform.class.getName()); // retrieveTransactionManager() == null
props.put("hibernate.hbm2ddl.auto", "update");

// after
props.put("hibernate.transaction.jta.platform",
    "org.hibernate.engine.transaction.jta.platform.internal.JBossAppServerJtaPlatform");
// or: run migrations with Flyway before boot, then hbm2ddl.auto=validate
Defensive patterns

Strategy: validation

Validate before calling

// before running schema tools in a JTA runtime, sanity-check the platform exposes a TM
TransactionManager tm = jtaPlatform.retrieveTransactionManager();
if (tm == null) {
  throw new IllegalStateException("JtaPlatform (" + jtaPlatform + ") exposes no TransactionManager; fix jta.platform config before DDL");
}

Try / catch

catch (org.hibernate.HibernateException e) {
  // named the useless JtaPlatform in its message: replace it with a runtime-correct
  // implementation (or externalize DDL to Flyway/Liquibase) instead of retrying
}

Prevention

When it happens

Trigger: Running schema tools (hibernate.hbm2ddl.auto=update/create, SchemaExport/SchemaUpdate) in a JTA-configured runtime where hibernate.transaction.jta.platform resolves to an implementation without a TransactionManager — e.g. a bare JtaPlatformBaseImpl subclass, a testing stub that only implements retrieveUserTransaction(), or an app-server platform used outside its server so its JNDI lookup returns null.

Common situations: Hand-rolled JtaPlatform classes in Spring Boot + embedded JTA (Atomikos/Narayana) setups; standalone apps hard-coding the platform class; migrations to a new app server whose JNDI names differ so the TM lookup silently fails.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/4e1157012640e4e4. Report an issue: GitHub.