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
- 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)
- If you implement JtaPlatform yourself, return a real TransactionManager from retrieveTransactionManager()
- Move DDL out of the JTA boot path: run Flyway/Liquibase before Hibernate starts and set hbm2ddl.auto to validate or none
- 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
- Use the JtaPlatform matching your runtime rather than custom stubs
- Run schema migrations before the JTA runtime boots
- Smoke-test retrieveTransactionManager() != null in startup checks
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
- Could not obtain TransactionManager from JtaPlatform
- Problem locating/validating JTA transaction
- UserTransaction reported transaction status as unknown
- Could not determine transaction status
- TransactionManager reported transaction status as unknwon
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/4e1157012640e4e4.
Report an issue: GitHub.