我有非常简单的persistance.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
注释)。
是否有任何自动机制来扫描 @Entity
类?
persistence.xml 有一个可以使用的 jar-file
。从 the Java EE 5 tutorial:
该文件定义了一个名为 OrderManagement
的持久性单元,它使用 JTA 感知数据源 jdbc/MyOrderDB
。 jar-file
和 class
元素指定托管持久性类:实体类、可嵌入类和映射超类。 jar-file
元素指定对包含托管持久性类的打包持久性单元可见的 JAR 文件,而 class
元素显式命名托管持久性类。
对于 Hibernate,请查看 Chapter2. Setup and configuration 以了解更多详细信息。
编辑: 实际上,如果您不介意不符合规范,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>
在 Java SE 环境中,您必须按照规范指定所有类:
必须在 Java SE 环境中指定所有命名的托管持久性类的列表以确保可移植性
和
如果不打算将包含在持久性单元根中的带注释的持久性类包含在持久性单元中,则应使用 exclude-unlisted-classes 元素。 exclude-unlisted-classes 元素不适用于 Java SE 环境。
(JSR-000220 6.2.1.6)
在 Java EE 环境中,您不必这样做,因为提供程序会为您扫描注释。
非正式地,您可以尝试在您的 persistence.xml 中设置 <exclude-unlisted-classes>false</exclude-unlisted-classes>
。此参数在 EE 中默认为 false
,在 SE 中默认为 true
。据我所知,EclipseLink 和 Toplink 都支持这一点。但是,如上所述,根据规范,您不应该依赖它在 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>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
不适用于 WildFly 8.2.1.Final + Hibernate 4.3.7
我需要persistence.xml 中的Class 元素吗?
不,你不一定。以下是您在 Eclipse 中的操作方式(Kepler 测试):
右键项目,点击属性,选择JPA,在Persistence class management中勾选Discover annotated classes automatically。
https://i.stack.imgur.com/oODvB.png
persistence.xml
。
对于那些在 Spring 中运行 JPA,从 3.1 版开始,您可以在 LocalContainerEntityManagerFactoryBean
下设置 packagesToScan
属性并完全摆脱 persistence.xml。
您可以为具有已编译类的文件夹提供 jar-file
元素路径。例如,当我为一些集成测试准备 persistence.xml 时,我添加了类似的内容:
<jar-file>file:../target/classes</jar-file>
对于 JPA 2+,这可以解决问题
<jar-file></jar-file>
扫描战争中的所有罐子以查找带注释的@Entity 类
java.lang.IllegalArgumentException: Unable to visit JAR file:
)。
在 SE 下,Hibernate 不支持 <exclude-unlisted-classes>false</exclude-unlisted-classes>
(另一张海报提到这适用于 TopLink 和 EclipseLink)。
有一些工具可以自动生成persistence.xml 的类列表,例如IntelliJ 中的导入数据库模式向导。在persistence.xml 中获得项目的初始类后,随着项目的进行,手动添加/删除单个类应该很简单。
不确定您是否正在做类似于我正在做的事情,但我使用 Maven 在单独的组件中使用 JAXB 从 XSD 生成源 java 负载。可以说这个工件被称为“基础模型”
我想导入这个包含 java 源代码的工件并在我的“基本模型”工件 jar 中的所有类上运行休眠,而不是明确指定每个类。我将“基本模型”添加为我的休眠组件的依赖项,但问题是persistence.xml 中的标签只允许您指定绝对路径。
我解决它的方法是将我的“基本模型”jar 依赖项明确地复制到我的目标目录并删除它的版本。因此,如果我构建我的“base-model”工件,它会生成“base-model-1.0-SNAPSHOT.jar”,复制资源步骤会将其复制为“base-model.jar”。
所以在你的休眠组件的pom中:
<!-- 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>
然后我在下一阶段“进程类”中调用休眠插件:
<!-- 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>
最后在我的 persistence.xml 中,我可以显式设置 jar 的位置:
<jar-file>target/dependency/base-model.jar</jar-file>
并添加属性:
<property name="hibernate.archive.autodetection" value="class, hbm"/>
这不是解决方案,而是对使用 Spring 的人的提示:
我尝试将 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
与设置 persistenceXmlLocation
一起使用,但我必须提供 <class>
元素(即使 persistenceXmlLocation
只是指向 META-INF/persistence.xml
)。
当 不 使用 persistenceXmlLocation
时,我可以省略这些 <class>
元素。
LocalContainerEntityManagerFactoryBean
设置中使用了 persistenceXmlLocation
属性。但即使我省略了 <class>
元素,所有查询都可以正常工作。它在 Spring/Hibernate/Maven 应用程序上。但是在您的提示中,您会说 “当不使用 persistenceXmlLocation 时,我可以省略这些 <class> 元素。” 但对我来说恰恰相反。
我不确定这个解决方案是否符合规范,但我想我可以分享给其他人。
依赖树
我的实体.jar
仅包含实体类。没有META-INF/persistence.xml
。
我的服务.jar
取决于 my-entities
。仅包含 EJB。
我的资源.jar
取决于 my-services
。包含资源类和 META-INF/persistence.xml
。
问题
我们如何将 my-resources 中的
我们如何同步
解决方案
直接(冗余?)依赖和资源过滤
我在 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 插件
使用 dependencyConvergence
规则,我们可以确保 my-entities
' 版本在直接和传递中都是相同的。
<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 和 Eclipselink 2.7.0。在我加载实体而不在 persistence.xml 中添加实体的情况下,我在 Jboss Standalone XML 中添加了以下系统属性:
<property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>