我已经(使用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上的许多其他人不同)。我是这样说的,因为我在我的主要内容中写了以下几行:
<...>
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:
修改 程序prety简单:没有hibernate,只有几个类从REST服务中检索一些信息并使用它,主要使用javax和w3c外部库。项目探险家的照片描绘了它的简洁。
编辑2.解决方案
虽然我不完全确定原因,但我找到了一种方法让它发挥作用。所以如果有人能回答为什么以下更改解决了这个问题,我很乐意将其标记为答案
我将eclipselink和mysql-connector-java jars添加到 src 目录中。 eclipselink.jar修复了这个问题,需要mysql-connector-java.jar,因为我收到了其他错误(我正在使用数据库afterall)。最后,我在
的run.bat文件中更改了一行java -cp ./src main.Main
到
java -cp ./src;./src/eclipselink.jar;./src/mysql-connector-java.jar; main.Main
答案 0 :(得分:0)
您的应用程序似乎是标准的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的项目。标准API的可重用性是标准化javax.persistence
接口最重要的情况。
也许您想知道,持久性API如何知道它应该委派所需功能的位置。它有多个钩子,它是如何找到的。可以使用persistence.xml
元素在provider
中包含主实现类的路径。或者,如果您将Eclipselink包含在类路径中,它就会起作用,因为Eclipselink库在标准化路径中包含特殊文本文件,其中包含所需信息。这个特殊文件位于路径META-INF/services/javax.persistence.spi.PersistenceProvider
的Eclipselink JAR中 - 是否响铃?