hibernate/hibernate-orm · critical · JtaPlatformException

Could not obtain Narayana TransactionManager instance

Error message

Could not obtain Narayana TransactionManager instance

What it means

NarayanaJtaPlatform.locateTransactionManager() reflectively calls the static transactionManager() on com.arjuna.ats.jta.TransactionManager. JtaPlatformException('Could not obtain Narayana TransactionManager instance') means the Arjuna JTA classes are not on Hibernate's classpath, or the Narayana transaction service is not initialized in this JVM, so the static accessor cannot return a manager.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/transaction/jta/platform/internal/NarayanaJtaPlatform.java:32

 *
 * @author Emmanuel Bernard
 * @author Steve Ebersole
 */
public class NarayanaJtaPlatform extends AbstractJtaPlatform {

	public static final String TM_CLASS_NAME = "com.arjuna.ats.jta.TransactionManager";
	public static final String UT_CLASS_NAME = "com.arjuna.ats.jta.UserTransaction";

	@Override
	protected TransactionManager locateTransactionManager() {
		try {
			return (TransactionManager) serviceRegistry().requireService( ClassLoaderService.class )
					.classForName( TM_CLASS_NAME )
					.getMethod( "transactionManager" )
					.invoke( null );
		}
		catch ( Exception e ) {
			throw new JtaPlatformException( "Could not obtain Narayana TransactionManager instance", e );
		}
	}

	@Override
	protected UserTransaction locateUserTransaction() {
		try {
			return (UserTransaction) serviceRegistry()
					.requireService( ClassLoaderService.class )
					.classForName( UT_CLASS_NAME )
					.getMethod( "userTransaction" )
					.invoke( null );
		}
		catch ( Exception e ) {
			throw new JtaPlatformException( "Could not obtain Narayana UserTransaction instance", e );
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add org.jboss.narayana.jta:narayana-jta with its transitive dependencies
  2. Ensure Narayana is bootstrapped (narayana-spring-boot-starter or explicit initialization) before Hibernate sessions are used
  3. Align hibernate-core and Narayana to a tested version combination
  4. Verify Class.forName("com.arjuna.ats.jta.TransactionManager") in the exact runtime classloader

Example fix

// before (pom.xml): only arjuna-core present, JTA facade missing
// after (pom.xml):
<dependency>
    <groupId>org.jboss.narayana.jta</groupId>
    <artifactId>narayana-jta</artifactId>
    <version>7.0.2.Final</version>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

Class.forName("com.arjuna.ats.jta.TransactionManager");
// and the static call Hibernate performs:
Class.forName("com.arjuna.ats.jta.TransactionManager").getMethod("transactionManager").invoke(null);

Prevention

When it happens

Trigger: hibernate.transaction.jta.platform=NarayanaJtaPlatform without org.jboss.narayana.jta:narayana-jta; Arjuna classes present but the transaction/recovery manager not started before Hibernate first needs it; a Narayana version where the class exists but transactionManager() throws during initialization.

Common situations: Spring Boot with a misconfigured Narayana starter; integration tests booting Hibernate before the transaction manager service; Narayana 5.x to 7.x upgrades changing initialization requirements.

Related errors


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