One of the most frustrating problems when learning Hibernate ORM and Jakarta Persistence is getting the first project to bootstrap successfully.

If Hibernate reports that it cannot find META-INF/persistence.xml, the problem is usually not Hibernate itself. It is typically the file name, the resource location, the build output, or the project's dependencies.

For a conventional Maven project, the file should normally be located here:

src/main/resources/META-INF/persistence.xml

Here are five things to check:

  1. Make sure the file is named exactly persistence.xml.
  2. Put it inside a directory named exactly META-INF.
  3. Make sure Maven or your IDE copies the resource onto the runtime classpath.
  4. Verify that the application actually contains a persistence.xml file.
  5. Use compatible Hibernate ORM and Jakarta Persistence dependencies.

1. Check the persistence.xml file name

The persistence configuration file must be named exactly persistence.xml. A misspelling, incorrect extension or incorrect case can prevent the persistence provider from finding it.

Watch for mistakes such as Persistence.xml, persistence.XML, persistense.xml or a hidden .txt extension added by an editor.

2. Put persistence.xml in META-INF

The Jakarta Persistence specification defines the configuration file as META-INF/persistence.xml at the root of the persistence unit.

In a standard Maven application, the normal source-tree location is:

src/main/resources/META-INF/persistence.xml

After Maven processes the project, you should normally find the resource here:

target/classes/META-INF/persistence.xml

3. Check the runtime classpath

Having the file in your source tree is not enough. It must also be available to the application at runtime.

With Maven's standard directory layout, files under src/main/resources are automatically treated as application resources. You normally should not need to manually add that directory to the Eclipse build path.

Run a clean build and verify that this file exists:

target/classes/META-INF/persistence.xml

If it does not, check your Maven resource configuration and make sure the project uses the conventional src/main/resources directory.

4. Use a current Hibernate ORM dependency

Modern Hibernate applications use the org.hibernate.orm Maven group ID. For Hibernate ORM 7.4, the dependency looks like this:

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>7.4.5.Final</version>
</dependency>

Maven's default dependency scope is compile, so there is normally no reason to add <scope>compile</scope> explicitly.

Also, do not add <type>pom</type> to the Hibernate Core dependency. Your application needs the Hibernate Core JAR on its runtime classpath.

Hibernate ORM 7.4 implements Jakarta Persistence 3.2 and requires a modern Java runtime. If your application uses a framework such as Spring Boot, let that framework's dependency management choose its supported Hibernate version rather than overriding Hibernate independently.

5. Create persistence.xml if it is missing

Sometimes the error is literal: the application does not contain a persistence.xml file.

If it was accidentally deleted, restore it from Git. If you are creating a new Jakarta Persistence application, add the file under src/main/resources/META-INF.

Jakarta Persistence 3.2 persistence.xml example

The current Jakarta Persistence 3.2 XML schema uses the Jakarta namespace and the persistence_3_2.xsd schema.

<?xml version="1.0" encoding="UTF-8"?>

<persistence
    xmlns="https://jakarta.ee/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        https://jakarta.ee/xml/ns/persistence
        https://jakarta.ee/xml/ns/persistence/persistence_3_2.xsd"
    version="3.2">

    <persistence-unit name="jpa-example">

        <properties>
            <property
                name="jakarta.persistence.jdbc.driver"
                value="com.mysql.cj.jdbc.Driver" />

            <property
                name="jakarta.persistence.jdbc.url"
                value="jdbc:mysql://localhost:3306/hibernate_examples" />

            <property
                name="jakarta.persistence.jdbc.user"
                value="hibernate-admin" />

            <property
                name="jakarta.persistence.jdbc.password"
                value="jpa3-password" />

            <property
                name="jakarta.persistence.schema-generation.database.action"
                value="create-and-drop" />
        </properties>

    </persistence-unit>

</persistence>

The important detail is that modern Jakarta Persistence configuration uses properties beginning with jakarta.persistence, not the old javax.persistence namespace.

Verify the persistence unit at startup

If the file is correctly packaged, this small bootstrap test should cause Jakarta Persistence to locate the persistence unit named jpa-example:

import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class JpaBootstrap {

    public static void main(String[] args) {

        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "jpa-example"
            );

        System.out.println(
            "Persistence unit loaded successfully."
        );

        emf.close();
    }
}

The name passed to Persistence.createEntityManagerFactory() must match the name attribute of the persistence-unit element.

Quick persistence.xml troubleshooting checklist

  • File name: persistence.xml
  • Maven location: src/main/resources/META-INF/persistence.xml
  • Build output: target/classes/META-INF/persistence.xml
  • Schema version: Jakarta Persistence 3.2
  • Schema file: persistence_3_2.xsd
  • Hibernate artifact: org.hibernate.orm:hibernate-core
  • Configuration namespace: jakarta.persistence.*
  • Persistence-unit name must match the name used when the application bootstraps JPA.

If all of these checks pass, Hibernate should be able to discover the persistence unit and bootstrap the Jakarta Persistence application successfully.