EntityManager没有名为X的持久性提供者

我正在开发使用JPA的JavaSE应用程序。 不幸的是,我调用后得到nullPersistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

下面你会发现:

  • 我的代码片段调用EntityManagerFactory并意外返回null
  • 我的persistence.xml文件
  • 我的项目结构

我的代码片段:

 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 ... } } 

我的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> 

我的项目结构:

这是我的项目的结构:

您必须将persistence.xml文件移到适当的位置。

更具体地说,将META-INF/persistence.xml文件添加到源文件夹的根目录。

在这种情况下,以下是适当的位置: src\main\java\META-INF\persistence.xml

这里是细节:( JPA规格

 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. 

持久化单元的根是这里的关键。

如果你是一个非Java EE应用程序

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

如果您在Java EE应用程序中 ,则以下内容有效

 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 

快速build议:

  • 检查persistence.xml是否在您的类path中
  • 检查hibernate提供程序是否在您的类path中

在独立应用程序(JavaEE之外)中使用JPA时,需要在某处指定持久性提供程序。 这可以用我知道的两种方式来完成:

  • 或者将提供者元素添加到持久性单元中: <provider>org.hibernate.ejb.HibernatePersistence</provider> (正如Chris的正确答案所述: https : //stackoverflow.com/a/1285436/784594 )
  • 或接口javax.persistence.spi.PersistenceProvider的提供者必须指定为服务,请参阅: http : //docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html (通常这是包括在将hibernate或其他JPA实现包含到类path中时

在我的情况下,我发现,由于maven misconfigurationhibernate-entitymanager.jar不包括作为依赖项,即使它是其他模块的瞬态依赖项。

请参阅这里的答案: 没有EntityManager的持久性提供者命名

我最近把NB 8.1升级到了8.2,突然遇到了这个问题,花了两天的时间打破了我的头脑。 最多8.1,删除processorpath(上面提到的其他)工作。 随着8.2,问题依然存在。

最后,我发现EclipseLink的缺省库(JPA 2.1)中缺lesseclipselink.jar。 我把文件添加到库的定义,瞧 – 它开始工作!

所以在我的情况下,一切都在class级的path,但我不得不补充

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

我认为这导致PersistenceProvider注册自己与javax类。 过去我也必须为JDBC驱动程序做类似的事情。

如果你不想移动你的META-INF文件夹(也许因为这是你的IDE创build它的地方,你不想混淆它),如果你正在使用Maven,你可以告诉Maven在哪里寻找META- INF使用<resources>标记。 请参阅: http : //maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html

在你的情况下:

 <build> <resources> <resource> <directory>src</directory> </resource> </resources> </build> 

不要给JPA依赖性明确

  <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0.2</version> </dependency> 

谢谢,
拉胡尔