hibernate/hibernate-orm · error · IllegalStateException

Illegal attempt to specify a SynchronizationType when buildi

Error message

Illegal attempt to specify a SynchronizationType when building an EntityManager from an EntityManagerFactory defined as RESOURCE_LOCAL (as opposed to JTA)

What it means

JPA requires EntityManagerFactory.createEntityManager(SynchronizationType, ...) to throw IllegalStateException when the persistence unit is RESOURCE_LOCAL. Hibernate enforces this in errorIfResourceLocalDueToExplicitSynchronizationType(): a SynchronizationType argument only makes sense when container/JTA transaction synchronization drives the EntityManager. RESOURCE_LOCAL EntityManagers manage their own resource transactions and cannot be handed to the container for synchronization.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java:912

	public Session createEntityManager(@Nullable Map<?,?> map) {
		validateNotClosed();
		return buildEntityManager( SYNCHRONIZED, map );
	}

	@Override
	@Nonnull
	public Session createEntityManager(@Nonnull SynchronizationType synchronizationType) {
		validateNotClosed();
		errorIfResourceLocalDueToExplicitSynchronizationType();
		return buildEntityManager( synchronizationType, null );
	}

	private void errorIfResourceLocalDueToExplicitSynchronizationType() {
		// JPA requires that we throw IllegalStateException in cases where:
		//		1) the PersistenceUnitTransactionType (TransactionCoordinator) is non-JTA
		//		2) an explicit SynchronizationType is specified
		if ( !transactionCoordinatorBuilder.isJta() ) {
			throw new IllegalStateException(
					"Illegal attempt to specify a SynchronizationType when building an EntityManager from an " +
							"EntityManagerFactory defined as RESOURCE_LOCAL (as opposed to JTA)"
			);
		}
	}

	@Override
	@Nonnull
	public Session createEntityManager(@Nonnull SynchronizationType synchronizationType, @Nullable Map<?,?> map) {
		validateNotClosed();
		errorIfResourceLocalDueToExplicitSynchronizationType();
		return buildEntityManager( synchronizationType, map );
	}

	private StatelessSession createEntityAgent() {
		validateNotClosed();
		return statelessSessionBuilder( false ).openStatelessSession();
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Drop the SynchronizationType argument for RESOURCE_LOCAL units: call emf.createEntityManager() or createEntityManager(map) instead
  2. If you truly need container-managed synchronized EMs, switch the persistence unit to JTA (jakarta.persistence.transactionType=JTA plus a JTA provider like Narayana/Atomikos)
  3. Branch on the transaction type: read jakarta.persistence.transactionType from emf.getProperties() and choose the createEntityManager overload accordingly
  4. In Spring, prefer injected EntityManager/@PersistenceContext or SharedEntityManagerCreator instead of manual factory calls

Example fix

// before
EntityManager em = emf.createEntityManager(SynchronizationType.SYNCHRONIZED);
// IllegalStateException: RESOURCE_LOCAL + explicit SynchronizationType

// after (RESOURCE_LOCAL unit)
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// ...
em.getTransaction().commit();
em.close();
Defensive patterns

Strategy: validation

Validate before calling

boolean isJta = "JTA".equalsIgnoreCase(
        String.valueOf(emf.getProperties().get("jakarta.persistence.transactionType")));
EntityManager em = isJta
        ? emf.createEntityManager(SynchronizationType.SYNCHRONIZED)
        : emf.createEntityManager();

Try / catch

try {
    return emf.createEntityManager(SynchronizationType.SYNCHRONIZED);
} catch (IllegalStateException e) {
    // RESOURCE_LOCAL unit: retry without a SynchronizationType
    return emf.createEntityManager();
}

Prevention

When it happens

Trigger: Calling emf.createEntityManager(SynchronizationType.SYNCHRONIZED) or (SynchronizationType.UNSYNCHRONIZED, map) on a persistence unit whose transaction type is RESOURCE_LOCAL (set in persistence.xml or jakarta.persistence.transactionType=RESOURCE_LOCAL). Typical when code written for a JTA server (WildFly) is reused in Spring Boot/Java SE, which defaults to RESOURCE_LOCAL.

Common situations: Porting an EAR from WildFly to Spring Boot where the same createEntityManager(SynchronizationType) call remains; scaffolding code generated for JTA environments used with a local HikariCP+RESOURCE_LOCAL setup; libraries that always pass SynchronizationType.SYNCHRONIZED for Jakarta EE compatibility.

Related errors


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