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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:34:11  来源:igfitidea点击:

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

javahibernateormjpaannotations

提问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 @Entityclasses?

是否有任何自动机制来扫描@Entity类?

采纳答案by Pascal Thivent

The persistence.xml has a jar-filethat 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-fileand classelements specify managed persistence classes: entity classes, embeddable classes, and mapped superclasses. The jar-fileelement specifies JAR files that are visible to the packaged persistence unit that contain managed persistence classes, while the classelement explicitly names managed persistence classes.

该文件定义了一个名为 的持久性单元OrderManagement,它使用了 JTA 感知数据源jdbc/MyOrderDB。所述jar-fileclass元素指定管持久类:实体类,可嵌入类和超类映射。该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.autodetectionproperty:

编辑:实际上,如果您不介意不符合规范,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 falsein EE and truein 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 和trueSE 中默认为。双方的EclipseLinkToplink的支持这是到目前为止,我可以告诉。但是,如上所述,根据规范,您不应该依赖它在 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.LocalContainerEntityManagerFactoryBeanwith setting persistenceXmlLocationbut with this I had to provide the <class>elements (even if the persistenceXmlLocationjust pointed to META-INF/persistence.xml).

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

When notusing persistenceXmlLocationI could omit these <class>elements.

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

回答by Christopher Yang

For those running JPA in Spring, from version 3.1 onwards, you can set packagesToScanproperty under LocalContainerEntityManagerFactoryBeanand get rid of persistence.xml altogether.

对于那些在 Spring 中运行 JPA 的人,从 3.1 版本开始,您可以packagesToScan在下面设置属性LocalContainerEntityManagerFactoryBean并完全摆脱persistence.xml。

Here's the low-down

这是低层

回答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-fileelement 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

enter image description here

在此处输入图片说明

回答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 in my-resourcesas 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.xmlready 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 dependencyConvergencerule, 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>