在Web应用程序中的JPA persistence.xml文件中引用jar文件的正确方法是什么?

27

这是persistence.xml的内容:

<persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>jdbc/test</non-jta-data-source>
    <jar-file>../../lib/app-services-1.0.jar</jar-file>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
这是一个web项目,因此部署单元是war文件,我试图引用的jar文件位于WEB-INF/lib/文件夹中,persistence.xml位于WEB-INF/classes/META-INF文件夹中。在部署时,它只是简单地告诉我:
"WARNING: Unable to find file (ignored): file:.../../lib/app-services-1.0.jar"。
我还尝试了我能想到的每条可能的路径,例如../lib/app-services-1.0.jar, lib/app-services-1.0.jar。请问正确的路径是什么?

你在哪个服务器上运行你的应用程序?JBoss?GlassFish?如果是JBoss,你根本不需要指定Hibernate;它是默认值。 - Matt Ball
2
GlassFish,Matt。我的问题不在于是否使用Hibernate,而在于如何告诉JPA提供程序路径以自动扫描实体的jar文件。 - Bobo
4个回答

22

查看jsr总是有效的!

8.2.1.6.3 Jar文件

可以使用jar-file元素指定一个或多个JAR文件,而不是或除了在mapping-file元素中指定的映射文件。如果指定了这些JAR文件,则将搜索这些JAR文件以查找托管持久化类,并处理其中找到的任何映射元数据注释,否则它们将使用由此规范定义的映射注释默认值进行映射。 这些JAR文件是相对于包含持久性单元根目录的目录或JAR文件指定的。

以下示例说明了使用jar-file元素引用其他持久性类的用法。这些示例使用约定,即名称以“PUnit”结尾的jar文件包含persistence.xml文件,而名称以“Entities”结尾的jar文件包含其他持久性类。

Example 1:
app.ear  
   lib/earEntities.jar  
   earRootPUnit.jar (with META-INF/persistence.xml )  
persistence.xml contains:  
   <jar-file>lib/earEntities.jar</jar-file>  

Example 2:
app.ear
   lib/earEntities.jar
   lib/earLibPUnit.jar (with META-INF/persistence.xml )
persistence.xml contains:
   <jar-file>earEntities.jar</jar-file>

Example 3:
app.ear
   lib/earEntities.jar
   ejbjar.jar (with META-INF/persistence.xml )
persistence.xml contains:
   <jar-file>lib/earEntities.jar</jar-file>

Example 4:
app.ear
    war1.war
       WEB-INF/lib/warEntities.jar
       WEB-INF/lib/warPUnit.jar (with META-INF/persistence.xml )
persistence.xml contains:
    <jar-file>warEntities.jar</jar-file>

Example 5:
app.ear
   war2.war
      WEB-INF/lib/warEntities.jar
      WEB-INF/classes/META-INF/persistence.xml
persistence.xml contains:
   <jar-file>lib/warEntities.jar</jar-file>

Example 6:
app.ear
    lib/earEntities.jar
    war2.war
    WEB-INF/classes/META-INF/persistence.xml
 persistence.xml contains:
    <jar-file>../../lib/earEntities.jar</jar-file>

Example 7:
app.ear
   lib/earEntities.jar
   war1.war
   WEB-INF/lib/warPUnit.jar (with META-INF/persistence.xml )
persistence.xml contains:
   <jar-file>../../../lib/earEntities.jar</jar-file>

正如你所看到的,关于 war 文件的示例并没有给出,以上所有 war 文件都在 ear 文件中!
但我测试了一下 war 文件,只有当我指定 jar 文件的绝对路径时才能正常工作,这对于生产环境来说并不是一个好的方法!


这是最佳答案,因为它给出了放在jar文件元素中的示例。同时也经过了验证可以正常工作。 - Archimedes Trajano
1
@Heidarzadeh 现在如何注入一个引用 earLibPUnit.jar 中持久化单元名称的 EntityManager,没有任何例子展示这个。 - Francis

13

仅在其他人意外遇到此问题时:当持久化单元作为企业归档文件(.ear)的一部分部署时,jar-file语句才有效。在所有其他情况下(.war),persistence.xml必须驻留在/META-INF/目录中,并且不能引用存储在持久化单元之外的类(请参见:http://javahowto.blogspot.com/2007/06/where-to-put-persistencexml-in-web-app.html)。就我所知,因此无法在WEB-INF/classes/META-INF中保留persistence.xml并引用不驻留在WEB-INF/classes中的类。


2
我曾认为像ear文件一样,war文件也可以这样做,但是尝试了很多次后,看到了你在这里的帖子,才明白原来对于war文件是不可能的!但有趣的是,当我在文件系统中指定jar文件的“绝对路径”时,它却奏效了!;) - Mehdi
4
你的答案完全不正确。实体类一定不能强制放在充当持久性根的JAR文件内部。完全不行。 我知道,在Weblogic、Glassfish和TomcatEE中,WAR文件可以完美包含一个内部JAR文件,该文件保存META-INF/persistence.xml并通过使用具有其他JAR文件名称的jar-file元素轻松地引用同一lib文件夹中的其他jar文件。你还可以在JPA 2.1 JSR的第367页和第368页中看到这一点。 话虽如此,让它在Wildfly 10中正常工作仍是一个挑战。 - 99Sono
从这里下载JSR:http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html。 - 99Sono

8
war2.war
      WEB-INF/lib/warEntities.jar
      WEB-INF/classes/META-INF/persistence.xml
persistence.xml contains:
   <jar-file>lib/warEntities.jar</jar-file>

这种格式适用于War文件。我正在使用Wildfly 8.2.0和JPA 2.1。

2
也适用于Payara Server 4.1.1.162 #badassfish(构建116)。 - Jin Kwon
1
当我在Jetty-9.4.10中使用hibernate-5.2.17作为JPA提供程序时,它对我不起作用,openJDK-8 :( - morgwai

0

我不确定这是否与您部署为WAR有关,但路径应该简单地是“app-sevices-1.0.jar”,而且该jar文件应该在Java EE应用程序的lib目录中。问题是:我不确定这是否适用于简化的“war” Java EE应用程序。我怀疑这仅适用于传统的Java EE部署文件(ear)。我建议测试制作一个EAR,其中包含一个Web应用程序的WAR,一个PU的JAR和您的其他用于app-services的JAR,就像传统的Java EE部署一样。

另一个需要注意的事项是不支持相对路径,并且并非所有供应商都支持在SE环境中使用它。


尝试了简单的“app-services-1.0.jar”路径,正如你所猜测的那样,它不起作用。所以我想问题是针对war文件,<jar-file>不能使用? - Bobo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接