繁体   English   中英

PersistenceException:没有名为EntityManager的持久性提供程序

[英]PersistenceException: No Persistence provider for EntityManager named

我已经用Eclipse编写了一个使用JPA的小程序。 现在,我想使用命令行手动编译并运行该程序。 我还将所有源文件放置在单独的目录中(不在Eclipse的工作空间内)。 目录如下:

directory
  |- src
  |   |- javax
  |   |   |- persistence
  |   |        |- <...>
  |   |- main
  |   |- META-INF
  |   |   |- javax
  |   |   |    |- persistence
  |   |   |- persistence.xml
  |   |
  |   |- <..>
  |- run.bat

注意:我特意有2个javax目录,其中包含所有类文件。

run.bat包含以下行:

javac -cp ./src ./src/main/Main.java
java -cp ./src main.Main

据我了解,我收到错误不是因为META-INF / persistence.xml文件存在问题(与stackoverflow上的许多其他人不同)。 我这样说是因为我在Main中写了以下几行:

<...>
Thread.currentThread().setContextClassLoader(new ClassLoader() {
            @Override
            public Enumeration<URL> getResources(String name) throws IOException {
                System.out.println("resource requested=" + name);
                if (name.equals("META-INF/services/javax.persistence.spi.PersistenceProvider")) {
        <--- MARK --->     return Collections.enumeration(Arrays.asList(new File("src/javax/persistence/spi/PersistenceProvider.class")
                            .toURI().toURL()));
                } else if (name.equals("META-INF/persistence.xml")) {
                    return Collections.enumeration(Arrays.asList(new File("src/META-INF/persistence.xml")
                            .toURI().toURL()));
                }
                return super.getResources(name);
            }
        });
emFactory = Persistence.createEntityManagerFactory("uzduotis");
<...>

因此,当我启动run.bat时,程序将输出:

resource name=name=META-INF/services/javax.persistence.spi.PersistenceProvider

(它永远不会到达程序要求“ META-INF / persistence.xml”资源的部分)

然后它坏了,给了我一个错误:

在此处输入图片说明

如果我将MARKED语句更改为

return super.getResources("src/" + name);

然后错误只说:

在此处输入图片说明

我想念什么?

Peristence.xml:

在此处输入图片说明

编辑:程序编写简单:没有休眠,只有几个类从REST服务检索一些信息并使用它,主要使用javax和w3c外部库。 项目浏览器的照片,描绘了其简单性。

在此处输入图片说明

编辑2.解决方案

尽管我不确定原因,但我找到了使其工作的方法。 因此, 如果有人可以回答以下更改为何解决了该问题的原因,我很乐意将其标记为答案

我在src目录中添加了eclipselink和mysql-connector-java jar。 eclipselink.jar解决了该问题,由于我遇到了其他错误(毕竟我正在使用数据库),因此需要mysql-connector-java.jar。 最后,我从以下位置更改了run.bat文件中的行:

java -cp ./src main.Main

java -cp ./src;./src/eclipselink.jar;./src/mysql-connector-java.jar; main.Main

您的应用程序似乎是标准的Java SE应用程序。 JPA不会自动运行,因为标准Java SE环境不包含JPA接口的任何实现。 Eclipse似乎将eclipselink添加到了幕后的类路径中,因此,当您从Eclipse中运行程序时,您的程序就可以工作。 但是,当您从命令行运行程序时,需要添加eclipselink ,这是一个包含JPA接口功能的库。

您可以尝试从eclipse项目生成Ant构建文件,然后查看是否将eclipselink添加到build.xml文件的类路径中。 甚至更好,我建议将您的项目转换为具有Maven构建的项目-您将能够使用Maven命令来构建和运行您的项目,就像Eclipse执行该项目一样(因为Eclipse在基于Maven的幕后使用Maven)项目)。

编辑-解释eclipselink在JPA中的作用

javax.persistence开头的包主要是接口,注释,实际上它们只有很少的类。 它们仅定义应用程序如何以标准方式与基础持久性机制进行通信。 另一方面,您还需要在标准JPA接口的实现(类)中包含库。 javax.persistence.Persistence只是一个外观,它将所有艰苦的工作委托给一个实现,该实现可以是Eclipselink,Hibernate或其他东西。

javax.persistence和EclipseLink之间的关系类似于接口和类之间的关系。 您可以在代码中使用接口,但是只有在某些时候为接口提供真实类时,应用程序才能运行。

也可以直接使用Eclipselink并跳过整个javax.persistence层,这与无需通过接口直接使用真实类是类似的。 但是随后您需要学习Eclipselink的内部API,并且无法更改Hibernate之类的Eclipselink库。 您也将无法将特定于Eclipselink的API的知识重用到使用Hibernate的项目中。 对于标准化的javax.persistence接口,标准API的可重用性是最重要的情况。

也许您想知道,持久性API如何知道应该在哪里委派所需的功能。 有多个钩子,如何找到它。 可以使用provider元素在persistence.xml包括主实现类的路径。 或者,如果您将Eclipselink包含到类路径中,它就可以正常工作,因为Eclipselink库在标准化路径中包含特殊文本文件,其中包含必需的信息。 这个特殊文件位于Eclipselink JAR内的META-INF/services/javax.persistence.spi.PersistenceProvider路径下-它会按铃响吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM