hibernate/hibernate-orm · error · PersistenceException

Unable to locate persistence units

Error message

Unable to locate persistence units

What it means

locatePersistenceUnits wraps any failure of the persistence.xml scan/parse pipeline in PersistenceException("Unable to locate persistence units", e). Note the distinction: when NO persistence.xml is found at all, Hibernate logs and returns an empty list - this exception means a persistence.xml WAS located but scanning/parsing it failed, and the cause carries the real problem.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java:159

			ClassLoader providedClassLoader,
			ClassLoaderService providedClassLoaderService) {
		try {
			final var parser =
					PersistenceXmlParser.create( integration, providedClassLoader, providedClassLoaderService );
			final var xmlUrls =
					parser.getClassLoaderService()
							.locateResources( "META-INF/persistence.xml" );
			if ( xmlUrls.isEmpty() ) {
				JPA_LOGGER.unableToFindPersistenceXmlInClasspath();
				return List.of();
			}
			else {
				return parser.parse( xmlUrls ).values();
			}
		}
		catch (Exception e) {
			JPA_LOGGER.unableToLocatePersistenceUnits( e );
			throw new PersistenceException( "Unable to locate persistence units", e );
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @implSpec The values passed in the {@code map} override values found
	 *           in {@link PersistenceUnitInfo#getProperties()} according to
	 *           the JPA specification.
	 */
	@Override
	public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map<?,?> map) {
		JPA_LOGGER.startingCreateContainerEntityManagerFactory( info.getPersistenceUnitName() );
		return getEntityManagerFactoryBuilder( info, map ).build();
	}

	/**
	 * {@inheritDoc}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inspect the wrapped cause - it names the file and the exact XML/parse problem
  2. Validate each persistence.xml against the Jakarta Persistence XSD matching your Hibernate version, and fix the reported construct
  3. Run 'mvn dependency:tree' / 'gradle dependencies' and exclude the older hibernate-core/javax.persistence that brought an incompatible parser or schema

Example fix

<!-- before: 2.x schema with Jakarta Hibernate 6+ -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.1">...</persistence>

<!-- after -->
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.0">...</persistence>
Defensive patterns

Strategy: try-catch

Validate before calling

// optional: parse-check persistence.xml before bootstrapping
try {
    javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder()
        .parse(cl.getResourceAsStream("META-INF/persistence.xml"));
} catch (Exception e) {
    throw new IllegalStateException("persistence.xml is not well-formed", e);
}

Try / catch

try {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("main");
} catch (javax.persistence.PersistenceException | jakarta.persistence.PersistenceException e) {
    if (e.getMessage() != null && e.getMessage().contains("Unable to locate persistence units")) {
        Throwable cause = e.getCause(); // the actual parse error - fix persistence.xml accordingly
        throw new IllegalStateException("Bad persistence.xml: " + cause, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A malformed persistence.xml (unbalanced tags, bad entity references), a document whose XSD version the parser rejects (e.g. a 2.x schema on a Jakarta 3.x Hibernate), duplicate/invalid unit declarations, or a ClassLoaderService failure while reading the located resources.

Common situations: Hand-edited persistence.xml with XML typos; mixing JPA 2.x persistence.xml with Hibernate 6+/Jakarta; two versions of hibernate-core on the classpath fighting over the parser; encoding issues in the XML.

Related errors


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