hibernate/hibernate-orm · error · HibernateException

Unable to suspend current JTA transaction in preparation for

Error message

Unable to suspend current JTA transaction in preparation for DDL execution

What it means

HibernateException from DdlTransactionIsolatorJtaImpl's constructor: a TransactionManager was found, but transactionManager.suspend() threw javax.transaction.SystemException while isolating DDL execution. Unlike the null-TM case, this is the JTA runtime itself failing the suspend operation (its error code is in the SystemException, which is unfortunately swallowed by this wrap).

Source

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

	}

	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;
	}

	@Override
	public Connection getIsolatedConnection() {
		return getIsolatedConnection(true);
	}

	@Override
	public Connection getIsolatedConnection(boolean autocommit) {
		if ( jdbcConnection == null ) {
			try {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Check the TransactionManager's own logs for the underlying suspend failure and its error code
  2. Run DDL before the JTA runtime starts or after it is fully healthy (external migration tool)
  3. Repair the JTA runtime configuration (object store, recovery ports) and retry startup
  4. Workaround: execute the schema update with a non-JTA (resource-local) configuration

Example fix

// before
props.put("hibernate.hbm2ddl.auto", "update"); // DDL runs through a broken JTA TM at boot

// after
// migrate before the app/TM boots, then only validate:
props.put("hibernate.hbm2ddl.auto", "validate");
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast if the TM is not operational before triggering DDL
try {
  Transaction suspended = transactionManager.suspend();
  transactionManager.resume(suspended); // probe round-trip
} catch (Exception probe) {
  throw new IllegalStateException("JTA TM not healthy; do not run DDL isolation", probe);
}

Try / catch

catch (org.hibernate.HibernateException e) {
  // suspend failed at the JTA level: check TM logs/error codes, repair the TM config,
  // or rerun DDL with a resource-local configuration — do not retry in the same state
}

Prevention

When it happens

Trigger: Schema export/update at startup inside a runtime whose JTA TransactionManager is broken, still initializing, shutting down, or in an inconsistent state, so suspend() raises SystemException.

Common situations: Narayana/Atomikos misconfiguration (corrupted object store, recovery manager not ready); deployment-time schema work racing TM startup or shutdown; TM/Hibernate version pairings that were never tested together.

Related errors


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