【发布时间】:2014-05-05 17:23:15
【问题描述】:
短版
我有一个使用 JPA 2.0 和 Hibernate 4.3.4 的 Java 项目。当我在 Eclipse 中运行它时,一切都很好。但是当我让 Eclipse 导出一个可运行的 JAR 时,麻烦就开始了,程序由于看似缺少持久性单元而崩溃......
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MyDBManager
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
...或看似未映射的类...
3024 Thread-4| FATAL DbManager : DBManager could not load countries from database.
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Country is not mapped [SELECT x FROM Country x]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:331)
背景
根据导出的类型(提取库、打包库还是复制库),我遇到了不同的错误,无法解决。我得到的最远的是最后一种方法,这也是我出于许可原因必须选择的方法,所以让我们专注于那个方法。
在这种情况下,导出的 JAR 无法查看其 persistence.xml。我稍后会具体说明,但首先是一些背景信息...
文件夹结构
- some_folder
- myproject_lib
- myproject.jar
- 我的项目包结构的根目录
- 元信息
- persistence.xml
文件persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="MyDBManager" transaction-type="RESOURCE_LOCAL">
<!-- <exclude-unlisted-classes>false</exclude-unlisted-classes> -->
<!-- <class>isi.eload.core.Country</class> -->
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<!-- Do not define a connection here - this is done by the DbManager according to the command line arguments -->
<property name="hibernate.id.new_generator_mappings" value="true" />
<!-- <property name="hibernate.archive.autodetection" value="class, hbm" /> -->
</properties>
</persistence-unit>
</persistence>
一旦我觉得 xml 已被实际处理(见下文),我就玩弄了注释行,但这并没有帮助。
JPA/Hibernate JAR
基本上来自4.3.4 Final Release:
- antlr-2.7.7
- dom4j-1.6.1
- hibernate-commons-annotations-4.0.4.Final
- hibernate-core-4.3.4.Final
- hibernate-entitymanager-4.3.4.Final
- hibernate-jpa-2.1-api-1.0.0.Final
- jandex-1.1.0.Final
- javassist-3.18.1-GA
- jboss-logging-3.1.3.GA
- jboss-logging-annotations-1.2.0.Beta1
- jboss-transaction-api_1.2_spec-1.0.0.Final
.
persistence.xml 失败
打包的元信息
正如我之前所暗示的,导出的 JAR 无法正确处理 persistence.xml。当我在上述文件夹结构中执行时,会抛出以下异常:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MyDBManager
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
此异常通常在找到文件时抛出,但给Persistence.createEntityManagerFactory 的持久性单元名称与文件中声明的任何持久性单元不匹配。但这绝对不是这里的情况!
我不知道为什么会抛出这个异常。
当我编辑 JAR 文件(虽然我不确定这种篡改本身不会导致问题)并清空或删除 persistence.xml 时,错误仍然存在。
另一个元信息
我的第一反应是复制 JAR 旁边的 meta-inf 文件夹:
- myproject_lib
- myproject.jar
- ...不变...
- 元信息
- persistence.xml
这似乎可行,因为现在可以创建实体管理器工厂。但随后没有找到实体,我认为这与实际使用的 persistence.xml 与 JAR 文件“不在同一类路径上”这一事实有关。
是否有关于如何解决此问题的链接或想法?最好通过强制 JAR 文件使用它自身包含的 meta-inf 文件夹。
【问题讨论】:
-
META-INF 需要大写。我怀疑您在 Windows 上运行,因此如果 Java 试图访问文件系统 META-INF/persistence.xml 将被操作系统自动转换为 meta-inf/persistence.xml。一旦你把它打包成一个 JAR,它就会区分大小写并停止工作。
-
哇! In 知道这将是一件微不足道的事情,但 那 简直太荒谬了!我浪费的时间......请将此作为答案,我将在 RTFM 的神殿上接受、投票和崇拜它。 ;)
-
成功了吗?如果是这样,我会将其发布为 cred 的答案;)
标签: java eclipse hibernate jpa