No Persistence provider for EntityManager named X

I am developing a JavaSE application using JPA. Unfortunately, I get null after calling: Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

Below you will find:

  • A snippet of my code that invokes EntityManagerFactory and unexpectedly returns null
  • My persistence.xml file
  • My project structure

Snippet of my code:

public class Main {
    private static final String PERSISTENCE_UNIT_NAME = "MeineJpaPU";
    private static EntityManagerFactory factory;

    public static void main(String[] args) {
        // I get null on this line!!!
       factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

       EntityManager em = factory.createEntityManager();
       // do stuff with entity manager
       ...
    }
}

My persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="MeineJpaPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <class>path.to.package.server.Todo</class>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
     <properties>       
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>       
            <property name="javax.persistence.jdbc.url"  value="jdbc:postgresql://localhost:5432/test"/>       
            <property name="javax.persistence.jdbc.user" value="postgres"/>       
            <property name="javax.persistence.jdbc.password" value="postgres"/>       
        </properties>
  </persistence-unit>
</persistence>

My project structure:

This is the structure of my project:


Solution 1:

You must move persistence.xml file to an appropriate location.

More specifically, add META-INF/persistence.xml file to the root of a source folder.

In this case, the following is an appropriate location: src\main\java\META-INF\persistence.xml

Here are the details: (taken from the JPA spec)

A persistence.xml file defines a persistence unit. The persistence.xml file is located in the META-INF directory of the root of the persistence unit.

The root of the persistence unit is the key here.

If you are a non-Java EE app

The jar file or directory whose META-INF directory contains the persistence.xml file is termed the root of the persistence unit.

If you are in a Java EE app, the following are valid

In Java EE environments, the root of a persistence unit must be one of the following:

  • an EJB-JAR file
  • the WEB-INF/classes directory of a WAR file[80]
  • a jar file in the WEB-INF/lib directory of a WAR file
  • a jar file in the EAR library directory
  • an application client jar file

Solution 2:

Quick advice:

  • check if persistence.xml is in your classpath
  • check if hibernate provider is in your classpath

With using JPA in standalone application (outside of JavaEE), a persistence provider needs to be specified somewhere. This can be done in two ways that I know of:

  • either add provider element into the persistence unit: <provider>org.hibernate.ejb.HibernatePersistence</provider> (as described in correct answer by Chris here: https://stackoverflow.com/a/1285436/784594)
  • or provider for interface javax.persistence.spi.PersistenceProvider must be specified as a service, see here: http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html (this is usually included when you include hibernate,or another JPA implementation, into your classpath

In my case, I found out that due to maven misconfiguration, hibernate-entitymanager.jar was not included as a dependency, even if it was a transient dependency of other module.

See also answers here: No Persistence provider for EntityManager named

Solution 3:

So in my case, everything was in the class path, but I had to add

Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider");

I think this caused the PersistenceProvider to register itself with the javax classes. I have had to do something similar for JDBC drivers in the past as well.

Solution 4:

I recently upgraded NB 8.1 to 8.2 and suddenly faced this problem and spent 2 days breaking my head to resolve. Up to 8.1, removing processorpath (mentioned above by others) worked. With 8.2, the problem persisted.

Finally, I found that the eclipselink.jar is missing in the default library of EclipseLink (JPA 2.1). I added the file to the definition of the library and voila - it started working!