0

正如上面的标签所声称的那样,这不是重复的。这个问题还没有被解答。

我正在尝试设置本教程以开始hyperjaxb在 Eclipse 项目中工作。我怎样才能让它看到持久性提供者? hbm2ddl尚未在数据库中创建表结构。这就是应用程序没有看到持久性提供程序的原因吗?还是因为无法从my试图调用它的目录访问persistence.xmlin的内容?以下是具体细节......这行代码: target/generated-sourcessrc/main/javaTestFunctions.java

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

 <?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>

persistence.properties是:

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项目的目录结构为:


**编辑: **

只是为了好玩,我将META-INF文件夹移动到与调用类相同的级别,但我得到了同样的错误。这是两个新的屏幕截图,显示了仍然抛出错误的 persistence.xml 位置:


第二次编辑:

Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider");在第 116 行添加,TestFunctions.java当我右键单击Main.java并执行时触发以下错误Run As..Java Application

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)  

这是新TestFunctions.setUpPersistence()方法:

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.eclipse.persistence.jpa.PersistenceProvider");为 时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 导致这个问题吗?

4

2 回答 2

3

我无法抗拒,这是我最后的帮助。:) 我正在为您和任何可能遇到类似问题的用户写这篇文章。

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

通常,当您使用 将现有的 Maven 项目导入 EclipseFile > Import... > Existing Maven Projects时,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.xmlJPA 规范指定。这是将从中加载持久性单元的地方。
    • 如果您已经生成了一个往返测试(xml-to-the-db-and-back),那么您还会在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>

重要的

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

从 Eclipse 中重新生成项目结构pom.xml并清理项目。打开您的.classpath文件并逐行与我发布的内容进行比较。但请先修复项目结构。

接下来,重要的是您要了解您不应该移动或拖放生成的代码。这不是正确的做法。不要这样做。请不要继续前进,直到您接受这是必要的。不要移动或修改生成的代码。如果这样做,您将承担此代码的责任。事物是这样生成的,因为它是这样工作的。因此,如果您更改它,它很可能不再起作用(它不适合您)。如果您需要更改任何内容,请更改pom.xml配置生成的配置,而不是生成的代码。

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

在此处输入图像描述

我能注意到的:

  • src\main\java包含maintest\MainTestFunctions。如果您正在尝试编写测试,请将您的测试类放入src\test\java,而不是src\main\java.
  • src\main\resources包含persistence.xml、和。sun-jaxb.episode_ 只应该在那里。 persistence.propertiesschema.xsdschema.xsd
    • persistence.xml并且sun-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,直到它与我发布的内容相同。我已经压缩并上传了绝对适合我的示例项目。您可以使用File > Import... > Existing Projects into Eclipse(而不是作为 Maven 项目)解压缩并导入它。

最后,您必须能够执行RoundtripTestJUnit 测试。测试可能会失败,但它必须运行,你不应该得到 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 构建中被忽略”)。在此错误消失之前不要继续前进。这是一个拦截器。

于 2014-10-14T21:46:26.793 回答
2

您应该传递的参数是persistence-unit。(不是文件名。)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0" ... >
    <persistence-unit name="generated">
        <class>generated.Items</class>
        <class>generated.Items$Item</class>
        <class>generated.PurchaseOrderType</class>
        <class>generated.USAddress</class>
    </persistence-unit>
</persistence>

所以应该是generated上面的persistence.xml

entityManagerFactory = Persistence.createEntityManagerFactory("generated", persistenceProperties);

为了你的坚持,应该是:

entityManagerFactory = Persistence.createEntityManagerFactory("org.jvnet.hyperjaxb3.ejb.tests.po", persistenceProperties);
于 2014-10-14T17:28:15.247 回答