Java 我需要persistence.xml 中的<class> 元素吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1780341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do I need <class> elements in persistence.xml?
提问by Micha? Mech
I have very simple persistance.xml file:
我有非常简单的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>
and it works.
它有效。
But when I remove <class>
elements application doesn't see entities (all classes are annotated with @Entity
).
但是当我删除<class>
元素时,应用程序看不到实体(所有类都用 注释@Entity
)。
Is there any automatic mechanism to scan for @Entity
classes?
是否有任何自动机制来扫描@Entity
类?
采纳答案by Pascal Thivent
The persistence.xml has a jar-file
that you can use. From the Java EE 5 tutorial:
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>
<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>
This file defines a persistence unit
named OrderManagement
, which uses a
JTA-aware data source jdbc/MyOrderDB
. The jar-file
and class
elements specify managed persistence classes: entity classes, embeddable classes, and mapped superclasses. The jar-file
element specifies JAR files that are visible to the packaged persistence unit that contain managed persistence classes, while the class
element explicitly names managed persistence classes.
该文件定义了一个名为 的持久性单元OrderManagement
,它使用了 JTA 感知数据源jdbc/MyOrderDB
。所述jar-file
和class
元素指定管持久类:实体类,可嵌入类和超类映射。该jar-file
元素指定对包含受管持久性类的打包持久性单元可见的 JAR 文件,而该class
元素显式命名受管持久性类。
In the case of Hibernate, have a look at the Chapter2. Setup and configurationtoo for more details.
在 Hibernate 的情况下,请查看第 2 章。设置和配置也了解更多详细信息。
EDIT:Actually, If you don't mind not being spec compliant, Hibernate supports auto-detection even in Java SE. To do so, add the hibernate.archive.autodetection
property:
编辑:实际上,如果您不介意不符合规范,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>
回答by Mads Mob?k
In Java SE environment, by specification you have to specify all classesas you have done:
在Java SE 环境中,根据规范,您必须像您所做的那样指定所有类:
A list of all named managed persistence classes must be specified in Java SE environments to insure portability
必须在 Java SE 环境中指定所有命名的托管持久性类的列表以确保可移植性
and
和
If it is not intended that the annotated persistence classes contained in the root of the persistence unit be included in the persistence unit, the exclude-unlisted-classes element should be used. The exclude-unlisted-classes element is not intended for use in Java SE environments.
如果不打算将持久性单元根中包含的带注释的持久性类包含在持久性单元中,则应使用 exclude-unlisted-classes 元素。exclude-unlisted-classes 元素不适用于 Java SE 环境。
(JSR-000220 6.2.1.6)
(JSR-000220 6.2.1.6)
In Java EE environments, you do nothave to do this as the provider scans for annotations for you.
在Java EE 环境中,您不必这样做,因为提供程序会为您扫描注释。
Unofficially, you can try to set <exclude-unlisted-classes>false</exclude-unlisted-classes>
in your persistence.xml. This parameter defaults to false
in EE and true
in SE. Both EclipseLinkand Toplinksupports this as far I can tell. But you should not rely on it working in SE, according to spec, as stated above.
非正式地,您可以尝试<exclude-unlisted-classes>false</exclude-unlisted-classes>
在您的persistence.xml 中设置。此参数false
在 EE 和true
SE 中默认为。双方的EclipseLink和Toplink的支持这是到目前为止,我可以告诉。但是,如上所述,根据规范,您不应该依赖它在 SE 中工作。
You can TRY the following (may or may not work in SE-environments):
您可以尝试以下操作(在 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>
回答by Chuck Stephanski
Hibernate doesn't support <exclude-unlisted-classes>false</exclude-unlisted-classes>
under SE, (another poster mentioned this works with TopLink and EclipseLink).
Hibernate<exclude-unlisted-classes>false</exclude-unlisted-classes>
在 SE 下不支持,(另一张海报提到这适用于 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.
有一些工具可以将类列表自动生成到persistence.xml,例如IntelliJ 中的导入数据库架构向导。一旦在persistence.xml 中获得了项目的初始类,随着项目的进行,手动添加/删除单个类应该很简单。
回答by Ethan Leroy
It's not a solution but a hint for those using Spring:
这不是解决方案,而是对使用 Spring 的人的提示:
I tried to use org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
with setting persistenceXmlLocation
but with this I had to provide the <class>
elements (even if the persistenceXmlLocation
just pointed to META-INF/persistence.xml
).
我尝试使用org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
with 设置,persistenceXmlLocation
但是我必须提供<class>
元素(即使persistenceXmlLocation
只是指向META-INF/persistence.xml
)。
When notusing persistenceXmlLocation
I could omit these <class>
elements.
当不使用persistenceXmlLocation
我可以省略这些<class>
元素。
回答by Christopher Yang
For those running JPA in Spring, from version 3.1 onwards, you can set packagesToScan
property under LocalContainerEntityManagerFactoryBean
and get rid of persistence.xml altogether.
对于那些在 Spring 中运行 JPA 的人,从 3.1 版本开始,您可以packagesToScan
在下面设置属性LocalContainerEntityManagerFactoryBean
并完全摆脱persistence.xml。
回答by Spencer Loveridge
Not sure if you're doing something similar to what I am doing, but Im generating a load of source java from an XSD using JAXB in a seperate component using Maven. Lets say this artifact is called "base-model"
不确定您是否正在做与我正在做的类似的事情,但是我使用 Maven 在单独的组件中使用 JAXB 从 XSD 生成源 java 负载。假设这个工件被称为“基础模型”
I wanted to import this artifact containing the java source and run hibernate over all classes in my "base-model" artifact jar and not specify each explicitly. Im adding "base-model" as a dependency for my hibernate component but the trouble is the tag in persistence.xml only allows you to specify absolute paths.
我想导入包含 java 源代码的这个工件,并在我的“基本模型”工件 jar 中的所有类上运行 hibernate,而不是明确指定每个类。我添加了“基本模型”作为我的休眠组件的依赖项,但问题是persistence.xml 中的标记只允许您指定绝对路径。
The way I got round it is to copy my "base-model" jar dependency explictly to my target dir and also strip the version of it. So whereas if I build my "base-model" artifact it generate "base-model-1.0-SNAPSHOT.jar", the copy-resources step copies it as "base-model.jar".
我绕过它的方法是将我的“基本模型”jar 依赖项显式复制到我的目标目录,并删除它的版本。因此,如果我构建我的“base-model”工件,它会生成“base-model-1.0-SNAPSHOT.jar”,而 copy-resources 步骤将其复制为“base-model.jar”。
So in your pom for the hibernate component:
所以在你的休眠组件的 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>
Then I call the hibernate plugin in the next phase "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>
and finally in my persistence.xml I can explicitly set the location of the jar thus:
最后在我的 persistence.xml 中,我可以明确地设置 jar 的位置:
<jar-file>target/dependency/base-model.jar</jar-file>
and add the property:
并添加属性:
<property name="hibernate.archive.autodetection" value="class, hbm"/>
回答by Arek Trzepacz
You can provide for jar-file
element path to a folder with compiled classes. For example I added something like that when I prepared persistence.xml to some integration tests:
您可以提供jar-file
带有已编译类的文件夹的元素路径。例如,当我为一些集成测试准备 persistence.xml 时,我添加了类似的内容:
<jar-file>file:../target/classes</jar-file>
回答by abbas
Do I need Class elements in persistence.xml?
我需要persistence.xml 中的Class 元素吗?
No, you don't necessarily. Here is how you do it in Eclipse (Kepler tested):
不,你不一定。以下是您在 Eclipse 中的操作方法(开普勒测试):
Right click on the project, click Properties, select JPA, in the Persistence class managementtick Discover annotated classes automatically.
右键单击项目,单击Properties,选择JPA,在Persistence class management 中勾选Discover annotated classes automatically。
回答by eriskooo
for JPA 2+ this does the trick
对于 JPA 2+,这可以解决问题
<jar-file></jar-file>
scan all jars in war for annotated @Entity classes
扫描战争中的所有罐子以获取带注释的@Entity 类
回答by Jin Kwon
I'm not sure this solution is under the spec but I think I can share for others.
我不确定这个解决方案是否符合规范,但我想我可以分享给其他人。
dependency tree
依赖树
my-entities.jar
我的实体.jar
Contains entity classes only. No META-INF/persistence.xml
.
仅包含实体类。没有META-INF/persistence.xml
。
my-services.jar
我的服务.jar
Depends on my-entities
. Contains EJBs only.
取决于my-entities
. 仅包含 EJB。
my-resources.jar
我的资源.jar
Depends on my-services
. Contains resource classes and META-INF/persistence.xml
.
取决于my-services
. 包含资源类和META-INF/persistence.xml
.
problems
问题
- How can we specify
<jar-file/>
element inmy-resources
as the version-postfixed artifact name of a transient dependency? - How can we sync the
<jar-file/>
element's value and the actual transient dependency's one?
- 我们如何将
<jar-file/>
element in指定my-resources
为瞬态依赖项的版本后缀工件名称? - 我们如何同步
<jar-file/>
元素的值和实际瞬态依赖的值?
solution
解决方案
direct (redundant?) dependency and resource filtering
直接(冗余?)依赖和资源过滤
I put a property and a dependency in my-resources/pom.xml
.
我在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>
Now get the persistence.xml
ready for being filtered
现在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 Plugin
Maven 执行器插件
With the dependencyConvergence
rule, we can assure that the my-entities
' version is same in both direct and transitive.
有了这个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>