hibernate/hibernate-orm · error · PersistenceException

Unknown persistence unit transaction type : {}

Error message

Unknown persistence unit transaction type : {}

What it means

Thrown by PersistenceXmlParser.parseTransactionType() as a PersistenceException when the transaction-type attribute of a <persistence-unit> in persistence.xml is non-empty but matches neither RESOURCE_LOCAL nor JTA (case-insensitive). The parser enumerates PersistenceUnitTransactionType.values() and falls through to this error for any other value.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceXmlParser.java:309

		else if ( persistenceUnitDescriptor.getNonJtaDataSource() != null ) {
			return RESOURCE_LOCAL;
		}
		else {
			return defaultTransactionType;
		}
	}

	private static PersistenceUnitTransactionType parseTransactionType(String value) {
		if ( isEmpty( value ) ) {
			return null;
		}
		else {
			for ( var transactionType : PersistenceUnitTransactionType.values() ) {
				if ( transactionType.name().equalsIgnoreCase( value ) ) {
					return transactionType;
				}
			}
			throw new PersistenceException( "Unknown persistence unit transaction type : " + value );
		}
	}

	private JaxbPersistenceImpl loadUrlWithJaxb(URL xmlUrl) {
		final String resourceName = xmlUrl.toExternalForm();
		try {
			var connection = xmlUrl.openConnection();
			// avoid JAR locking on Windows and Tomcat
			connection.setUseCaches( false );
			try ( var inputStream = connection.getInputStream() ) {
				return new ConfigurationBinder( classLoaderService )
						.bind( new StreamSource( inputStream ),
								new Origin( SourceType.URL, resourceName ) )
						.getRoot();
			}
			catch (IOException e) {
				throw new PersistenceException( "Unable to obtain input stream from [" + resourceName + "]", e );
			}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Set transaction-type to exactly RESOURCE_LOCAL or JTA (case-insensitive, no extra whitespace).
  2. Use RESOURCE_LOCAL when your app manages transactions via EntityTransaction (or Spring's resource-local setup); use JTA only with a real transaction manager (WildFly, Narayana, Atomikos).
  3. Validate persistence.xml against the Jakarta Persistence XSD to catch attribute typos early.
  4. If you actually wanted JTA, also provide the JTA data source and transaction coordinator config.

Example fix

<!-- before -->
<persistence-unit name="demo" transaction-type="LOCAL">

<!-- after -->
<persistence-unit name="demo" transaction-type="RESOURCE_LOCAL">
Defensive patterns

Strategy: validation

Validate before calling

// fail fast with your own message before the parser does
String tx = puElement.getAttribute("transaction-type");
if (!tx.isBlank() && !tx.equalsIgnoreCase("JTA") && !tx.equalsIgnoreCase("RESOURCE_LOCAL")) {
    throw new IllegalArgumentException("Invalid transaction-type '" + tx + "' in persistence.xml");
}

Prevention

When it happens

Trigger: Writing <persistence-unit name="x" transaction-type="LOCAL">, transaction-type="resource-local " (trailing space), "JTADataSource", or any typo/unsupported value in META-INF/persistence.xml; the error surfaces when Hibernate parses the XML at bootstrap.

Common situations: Typos in hand-edited persistence.xml; copy-paste from tutorials using non-standard values; believing values like "RESOURCE" or "NON_JTA" are accepted; XML editors not validating against the persistence XSD.

Related errors


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