Do I need <class> elements in persistence.xml?

我有一个非常简单的 persance.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">


<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
<class>pl.michalmech.eventractor.domain.User</class>
<class>pl.michalmech.eventractor.domain.Address</class>
<class>pl.michalmech.eventractor.domain.City</class>
<class>pl.michalmech.eventractor.domain.Country</class>


<properties>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>


</persistence>

而且成功了。

但是当我删除 <class>元素时,应用程序看不到实体(所有类都用 @Entity进行注释)。

Is there any automatic mechanism to scan for @Entity classes?

162048 次浏览

Xml 有一个可以使用的 jar-file:

<persistence>
<persistence-unit name="OrderManagement">
<description>This unit manages orders and customers.
It does not rely on any vendor-specific features and can
therefore be deployed to any persistence provider.
</description>
<jta-data-source>jdbc/MyOrderDB</jta-data-source>
<jar-file>MyOrderApp.jar</jar-file>
<class>com.widgets.Order</class>
<class>com.widgets.Customer</class>
</persistence-unit>
</persistence>

这个文件定义了一个持久性单元 命名为 OrderManagement,它使用一个 支持 JTA 的数据源 jdbc/MyOrderDBjar-fileclass元素指定托管持久性类: 实体类、可嵌入类和映射超类。jar-file元素指定包含托管持久性类的打包持久性单元可见的 JAR 文件,而 class元素显式命名托管持久性类。

在 Hibernate 的情况下,也可以查看 第2章。设置和配置以获得更多细节。

编辑: 实际上,如果您不介意不遵守规范,Hibernate 甚至在 Java SE 中也支持自动检测。为此,添加 hibernate.archive.autodetection属性:

<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
<!-- This is required to be spec compliant, Hibernate however supports
auto-detection even in JSE.
<class>pl.michalmech.eventractor.domain.User</class>
<class>pl.michalmech.eventractor.domain.Address</class>
<class>pl.michalmech.eventractor.domain.City</class>
<class>pl.michalmech.eventractor.domain.Country</class>
-->


<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class, hbm"/>


<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>

JavaSE 环境中,通过规范您必须指定所有类中,正如你所做的那样:

A list of all named managed persistence classes must be specified in Java SE environments to insure portability

还有

如果不希望持久性单元根中包含的带注释的持久性类包含在持久性单元中,那么应该使用排除-未列出的类元素。排除-未列出的类元素不适合在 JavaSE 环境中使用。

(JSR-0002206.2.1.6)

In Java EE environments, you do not have to do this as the provider scans for annotations for you.

在非正式的情况下,可以尝试将 <exclude-unlisted-classes>false</exclude-unlisted-classes>设置为尾数.xml。此参数在 EE 中默认为 false,在 SE 中默认为 trueinSE。据我所知,EclipseLink顶链都支持这一点。但是您不应该依赖它在 SE 中工作,根据规范,如上所述。

您可以尝试以下操作(可能在 SE 环境中工作,也可能不工作) :

<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
<exclude-unlisted-classes>false</exclude-unlisted-classes>


<properties>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>

Hibernate 不支持 SE 下的 <exclude-unlisted-classes>false</exclude-unlisted-classes>,(另一个帖子提到这可以与 TopLink 和 EclipseLink 一起工作)。

There are tools that will auto-generate the list of classes to persistence.xml e.g. the Import Database Schema wizard in IntelliJ. Once you've got your project's initial classes in persistence.xml it should be simple to add/remove single classes by hand as your project progresses.

这不是一个解决方案,而是对那些使用 Spring 的人的一个提示:

我试图在设置 persistenceXmlLocation时使用 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,但是在设置 persistenceXmlLocation时我必须提供 <class>元素(即使 persistenceXmlLocation只指向 META-INF/persistence.xml)。

没有使用 persistenceXmlLocation时,我可以省略这些 <class>元素。

对于那些在 Spring 中运行 JPA 的用户,从版本3.1开始,您可以在 LocalContainerEntityManagerFactoryBean下设置 packagesToScan属性,并完全去掉尾端的 restence.xml。

事情是这样的

不确定您是否正在做类似于我正在做的事情,但是我使用 JAXB 在一个单独的组件中使用 Maven 从 XSD 生成源 java 负载。假设这个工件叫做“基础模型”

我想导入这个包含 Java 源代码的工件,并在我的“基本模型”工件 jar 中的所有类上运行 hibernate,而不是显式地指定每个类。我将添加“ base-model”作为我的 hibernate 组件的依赖项,但问题在于尾声只允许您指定绝对路径。

我解决这个问题的方法是将我的“基本模型”jar 依赖项显式地复制到目标目录,并删除它的版本。因此,如果我构建“ base-model”工件,它会生成“ base-model-1.0-SNAPSHOT.jar”,而 copy-resources 步骤会将其复制为“ base-model. jar”。

所以在你的诗歌中冬眠的部分:

            <!-- We want to copy across all our artifacts containing java code
generated from our scheams. We copy them across and strip the version
so that our persistence.xml can reference them directly in the tag
<jar-file>target/dependency/${artifactId}.jar</jar-file> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<includeArtifactIds>base-model</includeArtifactIds>
<stripVersion>true</stripVersion>
</configuration>
</plugin>

然后,我在下一个阶段将 hibernate 插件称为“ process-class”:

            <!-- Generate the schema DDL -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.2</version>


<executions>
<execution>
<id>generate-ddl</id>
<phase>process-classes</phase>
<goals>
<goal>hbm2ddl</goal>
</goals>
</execution>
</executions>
<configuration>
<components>
<component>
<name>hbm2java</name>
<implementation>annotationconfiguration</implementation>
<outputDirectory>/src/main/java</outputDirectory>
</component>
</components>
<componentProperties>
<persistenceunit>mysql</persistenceunit>
<implementation>jpaconfiguration</implementation>
<create>true</create>
<export>false</export>
<drop>true</drop>
<outputfilename>mysql-schema.sql</outputfilename>
</componentProperties>
</configuration>
</plugin>

最后,我可以显式地设置 jar 的位置,如下所示:

<jar-file>target/dependency/base-model.jar</jar-file>

并添加属性:

<property name="hibernate.archive.autodetection" value="class, hbm"/>

可以为具有已编译类的文件夹提供 jar-file元素路径。例如,当我为一些集成测试准备尾声.xml 时,我添加了类似的东西:

 <jar-file>file:../target/classes</jar-file>

我是否需要尾随.xml 中的 Class 元素?

不,你不需要这么做。下面是你在 Eclipse 中的做法(开普勒测试) :

右键单击该项目,单击 物业,选择 JPA,在 Persistence class management中勾选 自动发现带注释的类

enter image description here

对于 JPA 2 + 来说,这是个好办法

 <jar-file></jar-file>

扫描所有罐子在注释@Entity 类的战争

我不确定这个解决方案是否符合规范,但我想我可以分享给其他人。

依赖关系树

我的实体,罐子

只包含实体类。没有 META-INF/persistence.xml

我的服务,罐子

取决于 my-entities。仅包含 EJB。

My-resources. jar

取决于 my-services。包含资源类和 META-INF/persistence.xml

问题

  • 我们如何在 my-resources中指定 <jar-file/>元素作为瞬态依赖的版本后置工件名称?
  • 如何同步 <jar-file/>元素的值和实际的瞬态依赖项的值?

解决方案

direct (redundant?) dependency and resource filtering

我在 my-resources/pom.xml中放置了一个属性和一个依赖项。

<properties>
<my-entities.version>x.y.z-SNAPSHOT</my-entities.version>
</properties>
<dependencies>
<dependency>
<!-- this is actually a transitive dependency -->
<groupId>...</groupId>
<artifactId>my-entities</artifactId>
<version>${my-entities.version}</version>
<scope>compile</scope> <!-- other values won't work -->
</dependency>
<dependency>
<groupId>...</groupId>
<artifactId>my-services</artifactId>
<version>some.very.sepecific</version>
<scope>compile</scope>
</dependency>
<dependencies>

现在让 persistence.xml做好过滤的准备

<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
<persistence-unit name="myPU" transaction-type="JTA">
...
<jar-file>lib/my-entities-${my-entities.version}.jar</jar-file>
...
</persistence-unit>
</persistence>

Maven Enforcer 插件

With the dependencyConvergence rule, we can assure that the my-entities' version is same in both direct and transitive.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>

并不是所有情况都是如此。

我使用的是 Jboss 7.0.8和 Eclipseselink 2.7.0。在我的例子中,为了加载实体,而不需要在 persence.XML 中添加相同的内容,我在 Jboss Standalone XML 中添加了以下系统属性:

<property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>