我需要persistence.xml中的<class>元素吗?
我有非常简单的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
。 从Java EE 5教程 :
<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/MyOrderDB
。 jar-file
和class
元素指定了托pipe持久性类:实体类,可embedded类和映射超类。 jar-file
元素指定对包含托pipe持久性类的打包持久性单元可见的JAR文件,而class
元素明确指定托pipe持久性类。
在Hibernate的情况下,看看Chapter2。 安装和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环境中指定所有命名的托pipe持久性类的列表,以确保可移植性
和
如果不打算将持久化单元的根中包含的带注释的持久化类包含在持久性单元中,则应使用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都支持这个function。 但是根据规范,如上所述,你不应该依赖它在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>
我需要在persistence.xml中的类元素?
不,你不一定。 下面是你如何在Eclipse(开普勒testing)中做到这一点:
右键单击项目,单击属性 ,selectJPA ,在持久性类pipe理中 自动发现带注释的类 。
对于那些在Spring中运行JPA的人,从版本3.1开始,你可以在LocalContainerEntityManagerFactoryBean下设置“pacakgesToScan”属性,完全去掉persistence.xml。
这是低调
对于JPA 2+,这个技巧
<jar-file></jar-file>
扫描战争中的所有jar子,注释@Entity类
Hibernate不支持SE下的<exclude-unlisted-classes>false</exclude-unlisted-classes>
(另一个提到的这个post可以和TopLink和EclipseLink一起使用)。
有一些工具可以自动生成persistence.xml的类列表,例如IntelliJ中的Import Database Schema向导。 一旦在persistence.xml中获得了项目的初始类,在项目进行时手动添加/删除单个类应该很简单。
您可以将jar-file
元素path提供给具有编译类的文件夹。 例如,当我为某些集成testing准备persistence.xml时添加了类似的内容:
<jar-file>file:../target/classes</jar-file>
不知道你是否正在做类似于我正在做的事情,但是Im使用JAXB在使用Maven的单独组件中使用XSD生成源代码Java的负载。 可以说这个神器被称为“基础模型”
我想导入包含java源代码的工件,并在我的“base-model”工件jar中的所有类上运行hibernate,而不是明确地指定每个类。 我添加“基础模型”作为我的hibernate组件的依赖,但麻烦的是persistence.xml中的标签只允许您指定绝对path。
我得到的方式是将我的“基本模型”jar依赖项明确地复制到我的目标目录中,并且还删除它的版本。 因此,如果我构build“base-model”工件,它生成“base-model-1.0-SNAPSHOT.jar”,则复制资源步骤将其复制为“base-model.jar”。
所以在你的pom中hibernate组件:
<!-- 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>
然后我在下一个阶段“process-classes”中调用hibernate插件:
<!-- 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"/>
这不是一个解决scheme,而是使用Spring的人的提示:
我尝试使用org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
来设置persistenceXmlLocation
但是为此我必须提供<class>
元素(即使persistenceXmlLocation
只是指向META-INF/persistence.xml
)。
当不使用persistenceXmlLocation
我可以省略这些<class>
元素。
我不确定这个解决scheme是否符合规范,但我认为我可以分享给其他人。
依赖关系树
我-entities.jar
仅包含实体类。 没有META-INF/persistence.xml
。
我-services.jar
取决于my-entities
。 仅包含EJB。
我-resources.jar
取决于my-services
。 包含资源类和META-INF/persistence.xml
。
问题
- 我们如何在
my-resources
指定<jar-file/>
元素作为临时性依赖项的版本后缀工件名称? - 我们如何同步
<jar-file/>
元素的值和实际的瞬态依赖的值?
解
直接(冗余?)依赖和资源过滤
我把一个属性和一个依赖项放在my-resources/pom.xml
。
<properties> <my-entities.version>xyz-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>