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 returnsnull
- 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:
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!