java - 没有名为persistence.xml的EntityManager的持久性提供程序

标签 java eclipse hibernate jpa hyperjaxb

这与上面的标签所声称的不是重复的。这个问题还没有被解答。

我正在尝试设置this tutorial以使hyperjaxb在eclipse项目中工作。我如何才能看到持久性提供程序? hbm2ddl尚未在数据库中创建表结构。这就是为什么应用程序看不到持久性提供程序的原因吗?还是因为persistence.xmltarget/generated-sources中的src/main/java内容无法从我的TestFunctions.java试图在其中调用的persistence.xml目录中访问?具体细节如下:这行代码:

entityManagerFactory = Persistence.createEntityManagerFactory("persistence.xml", persistenceProperties);  


抛出此错误:

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named persistence.xml
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at maintest.TestFunctions.setUpPersistence(TestFunctions.java:119)
    at maintest.Main.main(Main.java:10)


引发错误的代码在此方法中:

public void setUpPersistence(){
    final Properties persistenceProperties = new Properties();
    InputStream is = null;
    try {
        Class<? extends TestFunctions> c = getClass();
        ClassLoader cl = c.getClassLoader();
        is = cl.getResourceAsStream("persistence.properties");
        persistenceProperties.load(is);
    }catch (IOException i) {i.printStackTrace();}
    finally {if (is != null) {try {is.close();} catch (IOException ignored) {}}}
    entityManagerFactory = Persistence.createEntityManagerFactory("persistence.xml", persistenceProperties);
}  


persistence.properties

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <persistence-unit name="org.jvnet.hyperjaxb3.ejb.tests.po">
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.Items</class>
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.Items$Item</class>
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.PurchaseOrderType</class>
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.USAddress</class>
        </persistence-unit>
    </persistence>


META-INF是:

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.username=someusername
hibernate.connection.password=somepassword
hibernate.connection.url=jdbc:mysql://localhost/somedatabasename
hibernate.hbm2ddl.auto=create-drop
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
hibernate.jdbc.batch_size=0


eclipse项目的目录结构为:

  



**编辑:**

只是为了踢球,我将Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider");文件夹移到了与调用类相同的级别,但是出现了相同的错误。这是两个新的屏幕截图,显示了仍在其中引发错误的persistence.xml的位置:










第二编辑:

我在TestFunctions.java的第116行添加了Main.java,当我右键单击Run As..Java Application并执行TestFunctions.setUpPersistence()时,将触发以下错误:

Exception in thread "main" java.lang.ClassNotFoundException: org.eclipse.persistence.jpa.PersistenceProvider
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at maintest.TestFunctions.setUpPersistence(TestFunctions.java:116)
    at maintest.Main.main(Main.java:10)  


这是新的Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider");方法:

public void setUpPersistence() throws ClassNotFoundException{
    final Properties persistenceProperties = new Properties();
    InputStream is = null;
    try {
        Class<? extends TestFunctions> c = getClass();
        ClassLoader cl = c.getClassLoader();
        is = cl.getResourceAsStream("persistence.properties");
        persistenceProperties.load(is);
    }catch (IOException i) {i.printStackTrace();}
    finally {if (is != null) {try {is.close();} catch (IOException ignored) {}}}//org.jvnet.hyperjaxb3.ejb.tests.po
    Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider");
    entityManagerFactory = Persistence.createEntityManagerFactory(/*"org.jvnet.hyperjaxb3.ejb.tests.po"*//*"persistence.xml"*/"org.jvnet.hyperjaxb3.ejb.tests.po", persistenceProperties);
}


Class c = Class.forName("org.hibernate.ejb.HibernatePersistence");替换为Class c = Class.forName("javax.persistence.spi.PersistenceProvider");时,出现类似的错误。但是,javax.persistence.PersistenceException: No Persistence provider for EntityManager named org.jvnet.hyperjaxb3.ejb.tests.po不会引发任何错误,因此程序会继续运行,直到将同一hyperjaxb错误引发到更下游。

这是否能告诉我们更多有关错误原因的信息?另外,persistence.xml创建一个persistence.xml并将其放置在目标文件夹中。当persistence.xml处于该位置时,会发生此错误,并且如上所述,当我移动hyperjaxb时,该错误仍然存​​在。 是不是通过与eclipse配合不好而导致了此问题?

最佳答案

我无法抗拒,这是我最后的帮助。 :)我是为您和可能遇到类似问题的所有用户编写的。

我相信您只是在Eclipse项目配置中遇到问题。 Eclipse项目中的路径似乎不正确。

通常,当使用File > Import... > Existing Maven Projects将现有的Maven项目导入Eclipse时,m2eclipse应该分析Maven项目的结构并自动使用(.classpath.project文件)创建Eclipse项目。

这些项目中的路径是从Eclipse pom.xml派生的。因此,实际上您不应该创建/修改/添加/删除/复制/移动/任何Eclipse源文件夹。如果执行此操作,您的Eclipse项目将不再与Maven项目同步,并且您将得到非常奇怪的结果。

有时m2eclipse做得不好。有时您没有找到正确的源文件夹,某些东西丢失了等等。根据我的经验,随着时间的流逝,这种情况有了很大的改善,现在m2eclipse就像一种魅力。从我在您的奋斗中所看到的,可能是您使用的是旧版本的m2eclipse。也许不是,但是我还是建议检查一下。

接下来,有时m2eclispe仍会夹紧。在这种情况下,强烈建议您执行以下操作:


清理项目:Project > Clean...
更新Maven项目(Alt + F5)。确保从pom.xml更新项目配置




最后,您应该获得以下项目结构:



具体来说,您应该获得以下源文件夹:


src\main\java-主Java文件的源文件夹
src\main\resources-资源的源文件夹
target\generated-sources\xjc-生成代码的源文件夹。


重要提示:target\generated-sources不同于您,但target\generated-sources\xjc
此文件夹包含生成的Java类。 (Hyperjaxb向其中添加了JPA批注)。
它还包含META-INF\persistence.xml,这是一个持久性单元描述符。 META-INF\persistence.xml资源由JPA规范指定。这是从中加载持久性单元的位置。
如果您已经生成了往返测试(从xml到数据库的返回),那么您还将在某处看到RoundtripTest类。这是一个JUnit测试类,应该可以直接执行它。 (Run As > JUnit Test

src\test\java-测试类。
src\test\resources-测试资源


这是Maven项目的标准目录布局。唯一的特点是target\generated-sources\xjc源文件夹,其中包含由架构编译器生成的代码。即使这绝对是标准的,它也是Maven代码生成插件在target\generated-sources\some-tool目录中生成代码的常规约定。

下面,我从项目中发布.classpath文件:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/classes" path="src/main/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry including="**/*.java" kind="src" output="target/classes" path="target/generated-sources/xjc">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="target/test-classes" path="src/test/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="output" path="target/classes"/>
</classpath>


重要

如果您没有此目录结构(屏幕截图显示您没有),请不要继续。它将失败(对您有用)。首先修复您的项目结构。不要继续前进,不要尝试运行任何东西,您会遇到各种奇怪的事情,例如找不到资源等(您可以这样做)。

pom.xml重新生成项目结构,并在Eclipse中清理项目。打开您的.classpath文件,并将其与我发布的内容进行逐行比较。但是请先确定项目结构。

接下来,重要的是要了解不要移动或拖放生成的代码。这不是正确的事情。不要这样在您接受此命令之前,请不要继续。不要移动或修改生成的代码。如果这样做,您将承担此代码的责任。事物按其原样生成,因为它以这种方式工作。因此,如果您更改它,则很有可能不再起作用(不适用于您)。如果您需要更改任何内容,请更改pom.xml,它配置了生成而不是生成的代码。

现在,让我们根据以下屏幕截图分析您当前的项目结构:



我注意到的是:


src\main\java包含maintest\MainTestFunctions。如果要编写测试,请将测试类放入src\test\java,而不是src\main\java
src\main\resources包含persistence.xmlsun-jaxb.episodepersistence.propertiesschema.xsd。只有schema.xsd应该在那里。


persistence.xmlsun-jaxb.episode是生成的文件。并且,请参见上文,请勿移动它们。
persistence.properties定义与用于测试的数据库的连接。因此它必须位于测试资源中,即src\test\resources。将其放入src\main\resources最终会将此文件添加到生成的JAR中,就像告诉所有人用于测试的数据库的用户名和密码一样

src\test\java-可以,但是您的测试班级应该在这里。
src\test\resources-persistence.properties应该在这里。
target\generated-sources-这是错误的,应该是target\generated-sources\xjc


org.jvnet.hyperjaxb3.ejb.test.po软件包在target\generated-sources下。它是在target\generated-sources\xjc下生成的,所以我看到的意味着您已经移动了。不要这样做,请参见上文。
xjc显示为程序包。实际上,这是(错误地)将target\generated-sources配置为源文件夹之后的剩余内容。此文件夹必须包含所有生成的源,现在仅包含RoundtripTest。这意味着您移动了生成的代码。不要这样做,请参见上面的命令。



因此,上面显示的Eclipse项目配置无效。这是我为什么会发生这种情况的理论。我认为您的m2eclipse没有正确处理pom.xml,您可能缺少文件夹等。但是,不是让Eclipse项目文件正确生成我的m2eclipse,而是手动添加了target\generated-sources并开始移动生成的代码。这不是正确的方法。

请检查并重新检查您的.classpath,直到它等于我发布的内容为止。我已经压缩并uploaded我的示例项目肯定对我有用。您可以使用File > Import... > Existing Projects into Eclipse解压缩并导入它(不是Maven项目)。

最后,您必须能够将RoundtripTest作为JUnit测试执行。测试可能会失败,但是它必须运行,您不应该获得NPE等。我手头没有MySQL数据库,所以这是我现在得到的:

Detected [file:/C:/Projects/workspaces/hj3/hyperjaxb3-ejb-template-basic-0.6.0/target/classes/META-INF/persistence.xml].
    RoundtripTest

Loading entity manager factory properties.
    RoundtripTest

Loading entity manager factory properties from [file:/C:/Projects/workspaces/hj3/hyperjaxb3-ejb-template-basic-0.6.0/target/test-classes/persistence.properties].
    RoundtripTest

Could not obtain connection to query metadata
    org.hibernate.cfg.SettingsFactory

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.net.ConnectException
MESSAGE: Connection refused: connect


这意味着实体管理器已正确启动,但无法连接到数据库。如果已在src\test\resources\persistence.properties中正确配置了测试数据库,则应该可以连接到数据库。如果将po.xml文件放入src\test\samples,则往返测试将:


解组该文件
保存到数据库
装回
与原始结果比较


在开始您自己的实验之前,请先进行Roundrip测试。不要复制代码,不要修改代码,不要试图将其弯曲到目录结构中。它必须按原样运行。直到它继续前进为止。

祝好运。

更新。

您可能还面临着无法解决的依赖性问题。请确保您的依赖关系已正确解决。这是我看到的:



如果看不到,那就不好了。您的工作区出了点问题。检查Eclipse中是否有任何错误消息。也许你有这样的东西:

Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:hibernate3-maven-plugin


首先快速修复它(“将目标永久标记为……在Eclispe构建中被忽略”)。在此错误消失之前,请不要继续。这是一个障碍。

关于java - 没有名为persistence.xml的EntityManager的持久性提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26366556/

相关文章:

java - 使用输入扫描器执行 while 循环

Java对象和原始类型变量混淆

java - 更改 Eclipse 运行时环境

spring - StaleObjectStateException : Row was updated or deleted by another transaction?

java - 使用 Java BigIntegers 在 RSA 中解密时,如何在原始数据的开头保留零字节?

java - 如何使用 GDB 从 native 调用调试到 java 函数?

java - 如何在黑莓中导入 Java 插件中的项目

eclipse - 如何将 TestNG javadoc 连接到 Eclipse?

java - @GenerateValue JPA 标签中的错误

java - Hibernate中的根异常是什么