web-dev-qa-db-ja.com

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クラスをスキャンする自動メカニズムはありますか?

106
Michał Mech

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>

このファイルは、JTA対応のデータソースjdbc/MyOrderDBを使用するOrderManagementという名前の永続性ユニットを定義します。 jar-fileおよびclass要素は、管理された永続性クラス(エンティティークラス、埋め込み可能クラス、およびマッピングされたスーパークラス)を指定します。 jar-file要素は、管理された永続性クラスを含むパッケージ化された永続性ユニットに表示されるJARファイルを指定し、class要素は管理された永続性クラスを明示的に指定します。

Hibernateの場合、詳細については Chapter2。Setup and configuration も参照してください。

EDIT:実際、仕様に準拠していないことを気にしない場合、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>
78
Pascal Thivent

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です。 EclipseLinkToplink の両方が、私が知る限りこれをサポートしています。ただし、前述のように、仕様に従って、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>
43
Mads Mobæk

Persistence.xmlにClass要素が必要ですか?

いいえ、必ずしもそうとは限りません。 Eclipseでの実行方法は次のとおりです(ケプラーテスト済み)。

プロジェクトを右クリックし、Propertiesをクリックして、JPAを選択します。Persistence class management tick アノテーション付きクラスを自動的に検出

enter image description here

13
abbas

バージョン3.1以降のJPAをSpringで実行している場合は、packagesToScanの下にLocalContainerEntityManagerFactoryBeanプロパティを設定し、persistence.xmlを完全に削除できます。

これがローダウンです

11

Hibernateは<exclude-unlisted-classes>false</exclude-unlisted-classes>をSEでサポートしていません(これはTopLinkおよびEclipseLinkで動作することを述べた別のポスター)。

クラスのリストをpersistence.xmlに自動生成するツールがあります。 IntelliJのデータベーススキーマのインポートウィザード。 persistence.xmlでプロジェクトの初期クラスを取得したら、プロジェクトの進行に合わせて手動で単一のクラスを簡単に追加/削除する必要があります。

7

コンパイルされたクラスを含むフォルダーへのjar-file要素パスを提供できます。たとえば、persistence.xmlをいくつかの統合テストに準備したときに、そのようなものを追加しました。

 <jar-file>file:../target/classes</jar-file>
7
Arek Trzepacz

jPA 2+の場合、これはトリックを行います

 <jar-file></jar-file>

戦争中のすべてのjarでアノテーション付き@Entityクラスをスキャンします

7
eriskooo

あなたが私がやっていることに似ているかどうかはわかりませんが、Mavenを使用して別のコンポーネントでJAXBを使用してXSDからソースJavaの負荷を生成しています。このアーティファクトは「ベースモデル」と呼ばれるとしましょう

Javaソースを含むこのアーティファクトをインポートし、「ベースモデル」アーティファクトjar内のすべてのクラスでhibernateを実行し、それぞれを明示的に指定したくありませんでした。 hibernateコンポーネントの依存関係として「ベースモデル」を追加していますが、問題はpersistence.xmlのタグで絶対パスのみを指定できることです。

私がやってきた方法は、「ベースモデル」jar依存関係をターゲットディレクトリに明示的にコピーし、そのバージョンも削除することです。そのため、「ベースモデル」アーティファクトをビルドすると「ベースモデル1.0 1.0 SNAPSHOT.jar」が生成されますが、copy-resourcesステップはそれを「ベースモデル.jar」としてコピーします。

したがって、Hibernateコンポーネントの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>

次に、次のフェーズで「プロセスクラス」の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"/>
4

これは解決策ではなく、Springを使用している人へのヒントです。

persistenceXmlLocationを設定してorg.springframework.orm.jpa.LocalContainerEntityManagerFactoryBeanを使用しようとしましたが、これでは<class>要素を提供する必要がありました(persistenceXmlLocationMETA-INF/persistence.xmlを指している場合でも)。

notを使用してpersistenceXmlLocationを使用すると、これらの<class>要素を省略できます。

3
Ethan Leroy

このソリューションが仕様の下にあるかどうかはわかりませんが、他の人と共有できると思います。

依存ツリー

my-entities.jar

エンティティクラスのみが含まれます。いいえMETA-INF/persistence.xml

my-services.jar

my-entitiesに依存します。 EJBのみが含まれます。

my-resources.jar

my-servicesに依存します。リソースクラスとMETA-INF/persistence.xmlが含まれます。

問題点

  • <jar-file/>my-resources要素を、一時依存関係のバージョンが後置されたアーティファクト名として指定するにはどうすればよいですか?
  • <jar-file/>要素の値と実際の一時的な依存関係の値を同期するにはどうすればよいですか?

解決

直接(冗長?)依存関係およびリソースフィルタリング

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>
2
Jin Kwon

必ずしもすべての場合において。

Jboss 7.0.8およびEclipselink 2.7.0を使用しています。 persistence.xmlに同じものを追加せずにエンティティをロードする私の場合、Jboss Standalone XMLに次のシステムプロパティを追加しました。

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

0
Gandhi