persistence.xmlに<class>要素が必要ですか?


110

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

回答:


78

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>

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

Hibernateの場合は、第2章をご覧ください。詳細については、セットアップと構成も。

編集:実際には、仕様に準拠しなくても構わない場合、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>

13
わかりましたが、エンティティ(@Entity)は別のMavenプロジェクトにあるため、jarファイル名はビルドごとに変わる可能性があります。特定のパッケージまたはクラスパスのすべてをスキャンするものを探しています。私は、persistence.xmlファイルに多数の<class>要素を入力するのが面倒です。
のMichałメカ

すべてのビルドで?!理由は質問しませんが...フィルタリングを使用してこれを解決できます。
Pascal Thivent 2009年

正確には誰でもありませんが、私は変化に抵抗したいです。
のMichałメカ

5
古代のスレッドですが、jpa-maven-pluginをご覧ください。
Laird Nelson

persistence.xmlで<mapping-file>要素(エンティティのリストを含む)を使用できるため、使用されるファイルの名前を同じに保ち、参照されるjarのビルドにそれらを統合できます。
med_alpa 2016年

44

Java SE環境、仕様によって、あなたはすべてのクラスを指定する必要があり、あなたが行ったように:

移植性を保証するために、名前付きのすべてのマネージ永続クラスのリストをJava SE環境で指定する必要があります

そして

永続性ユニットのルートに含まれる注釈付き永続性クラスを永続性ユニットに含めることを意図していない場合は、exclude-unlisted-classes要素を使用する必要があります。exclude-unlisted-classes要素は、Java SE環境での使用を目的としていません。

(JSR-000220 6.2.1.6)

Java EE環境では、あなたがいないあなたのための注釈のプロバイダスキャンとしてこれを行う必要があります。

非公式に、<exclude-unlisted-classes>false</exclude-unlisted-classes>persistence.xmlで設定を試みることができます。このパラメーターのデフォルトはfalse、EEおよびtrueSEです。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>

2
<exclude-unlisted-classes>false</exclude-unlisted-classes>WildFly 8.2.1では機能しませんでした。Final+ Hibernate 4.3.7
Andreas Dietrich

12

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

いいえ、必ずしもそうとは限りません。以下は、Eclipseでそれを行う方法です(Keplerでテスト済み)。

右クリックし、プロジェクトをクリックして[プロパティ]を選択し、JPAの中で、永続クラス管理 TICK の発見は自動的にクラスを注釈付き

ここに画像の説明を入力してください


9
なぜ賛成ですか?OPはEclipseについてさえ言及しておらず、この回答は、このEclipse機能が内部で何を行うかを示していないため、IDEなしでそれを行うことができます。
Artem Novikov

2
@Artem Novikov:さまざまな環境から質問が頻繁に発生するため、これは厳しいと思います。ここでは、役立つヒントや役立つヒントを提供したいと考えています。(私と同じように)Eclipseはこのように開発するための一般的なIDEであり、内部ではそれほど重要ではないので便利ですが、関連するすべてのワークスペースプロジェクト(たとえば、私のプロジェクトが依存しているプロジェクト)が含まれると思います。
アンドレアスディートリッヒ

stackoverflow.com/questions/17951297/…素敵なトリックですが、エンティティがpersistence.xmlと同じクラスローダーで終了する場合にのみ機能するようです
Pierluigi Vernetto 2017年

@abbas persistence.xmlEclipseが生成するものを示してください。
Frans

12

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

これがローダウンです


私のために働いた!シナリオは、春4 +休止状態+ jpa2 + mavenでした。JUnitテストではエンティティが見つかりませんでしたが、この設定で問題は解決しました。
SatA 2014

8

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

 <jar-file>file:../target/classes</jar-file>

これは私が探していたものです!
xtian 2017

EclipseLinkでも動作します!
ボンベ、

8

JPA 2+の場合、これでうまくいきます

 <jar-file></jar-file>

注釈付きの@Entityクラスについて、戦争中のすべてのjarをスキャンします


2
これについてもっと情報がありますか?これは偶然に機能しますか、それとも仕様に記載されていますか?実装に依存していますか?
マーカス

スキャナーは、AbstractScannerImpl、hibernateを拡張するクラスにあります-バグか機能かは
わかり

1
Hibernate 5.1.2.FinalのJava SEでは、このソリューションは機能しません。Hibernateはjarファイル名(java.lang.IllegalArgumentException: Unable to visit JAR file:)を想定しています。
2016年

1
動作します!:) WildFly 8.2.1.Final + Hibernate 4.3.7.Finalを使用
Andreas Dietrich

Thx man、たくさん検索しました、そしてこれは利用可能な最も近いソリューションです。Wildfly10 + Hibernate 5.0.7が動作しています。
boutta 2017

7

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

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


Java SEでのエンティティの自動検出は、JPAの一部ではありません。これに依存するアプリケーションは移植できません。
Pascal Thivent

4

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

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

私が解決した方法は、「ベースモデル」jarの依存関係を明示的にターゲットディレクトリにコピーし、そのバージョンを取り除くことです。したがって、「base-model」アーティファクトをビルドすると、「base-model-1.0-SNAPSHOT.jar」が生成されますが、copy-resourcesステップは、それを「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>

次に、次のフェーズで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"/>

3

これは解決策ではありませんが、Springを使用する人のためのヒントです。

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

使用しない場合persistenceXmlLocationこれらの<class>要素を省略できます。


persistenceXmlLocationは自分のLocalContainerEntityManagerFactoryBean設定でプロパティを使用しました。しかし、<class>要素を省略しても、すべてのクエリは機能しています。そのSpring / Hibernate / Mavenアプリケーションにあります。しかし、「persistenceXmlLocationを使用しない場合は、これらの<class>要素を省略できる」とあなたは言います。しかし、私にとってはその逆です。
ラッキー、

@Ethanは正しいです。persistenceXmlLocationがpackagesToScanをオーバーライドするためです-ソースを調べると。したがって、packagesToScanを使用する場合は使用しないでください。
Artem Novikov

2

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

依存ツリー

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エンフォーサプラグイン

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>

0

必ずしもすべての場合ではありません。

Jboss 7.0.8とEclipselink 2.7.0を使用しています。persistence.xmlにエンティティを追加せずにエンティティをロードする場合、JbossスタンドアロンXMLに次のシステムプロパティを追加しました。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.