web-dev-qa-db-ja.com

JPA 2.0:*異なるjar *からのPersistenceUnitへのエンティティクラスの自動追加

Mavenで構築されたCDIベースのJava SEアプリは、coreモジュールと他のモジュールを持っています。
コアには、persistence.xmlおよびいくつかのエンティティがあります。モジュールには追加のエンティティがあります。

永続性ユニットのスポットライトにエンティティを追加するにはどうすればよいですか?

Hibernateのマニュアルを読みました http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html#setup-configuration-packaging

これらのSOの質問も見ました

Hibernateがロードされたすべてのクラスをスキャンするか、他のjarから設定ファイルを取得するソリューションを探しています(たとえば、CDIがbeans.xmlで行うように)。

私のアプリはSpringを使用していません。私は移植性を主張しません-私はHibernateに固執します。

  • そのような解決策はありますか?
  • persistence.xmlからPUを作成し、プログラムでクラスを追加する方法はありますか?
  • @ Entityクラスを作成後にEntityManagerFactoryに追加できますか?

更新:org.​hibernate.​ejb.​Ejb3Configurationで見つけた:

public Ejb3Configuration configure(String persistenceUnitName, Map integration)  

http://docs.jboss.org/hibernate/entitymanager/3.6/javadocs/

38
Ondra Žižka

それを解決する方法はいくつかあります。

  1. persistence.xmlで<class>要素が必要ですか? で説明されているように、hibernate.archive.autodetectionプロパティとHibernateは、クラスパスからすべての注釈付きクラスを検索できるはずです。ただし、これはJPA仕様に準拠していません。

  2. Spring 3.1.2(またはおそらく少し前)のSpringをLocalContainerEntityManagerFactoryBeanで使用している場合は、packageToScanを定義して、LocalContainerEntityManagerFactoryBeanにクラスパスでスキャンするように要求できます。すべての注釈付きクラスを検索します。繰り返しますが、JPA仕様に準拠していません。

  3. Mavenをビルドツールとして使用していました。何年も前に、ビルドプロセス中にpersistence.xmlを生成する小さなプラグインを作成しました。プラグインは、ビルドクラスパスからスキャンしてすべての注釈付きクラスを見つけ、生成されたpersistence.xmlにリストします。これは最も面倒ですが、結果はJPA仕様に準拠しています。 1つの欠点(ほとんどの人には当てはまらない)は、実行時ではなくビルド時にルックアップが発生することです。つまり、エンティティJARがデプロイ時または実行時にのみ提供され、ビルド時には提供されないアプリケーションがある場合、このアプローチは機能しません。

11
Adrian Shum

Ejb3Configurationは4.3.0で削除されました。 Hibernateのインテグレーターを作成したくない場合は、hibernate.ejb.loaded.classesプロパティを使用できます。

properties.put(org.hibernate.jpa.AvailableSettings.LOADED_CLASSES, entities);
Persistence.createEntityManagerFactory("persistence-unit", properties);

entitiesは、エンティティクラスのList<Class>です。

7
Ignacio Baca

Persistence.xmlをWARファイルに配置するセットアップが少し異なりますが、その依存関係の一部には、永続性ユニットに含めるようにクラス化された@Entityアノテーションが含まれています。

#3で説明したAdrian ShumのようにMavenを使用して問題を解決しましたが、@ Entityアノテーションをスキャンするjarを含む要素を使用しました。

追加のエンティティを含む各依存関係のプロパティをmy-web/pom.xmlに追加しました。私のjarファイルはすべてMavenマルチプロジェクトビルドの一部であるため、私にとっては次のように見えます。

<properties>
    <common.jar>common-${project.version}.jar</common.jar>
    <foo.jar>foo-${project.version}.jar</foo.jar>
</properties>

その後、persistence.xmlに以下を追加します

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" ... >
    <persistence-unit name="primary">
        <jta-data-source>Java:jboss/datasources/mysource</jta-data-source>

        <jar-file>lib/${common.jar}</jar-file>
        <jar-file>lib/${foo.jar}</jar-file>

        ...
    </persistence-unit>
</persistence>

最後に、web/pom.xmlのmaven-resource-pluginを設定して、persistence.xmlの$ expressionsをPOMで設定されたプロパティに置き換えます

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
      <includes>
        <include>**/persistence.xml</include>
      </includes>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>false</filtering>
      <excludes>
        <exclude>**/persistence.xml</exclude>
      </excludes>
    </resource>
  </resources>
  ...
</build>
6

私は同じ問題を経験しましたが、残念ながら簡単な解決策はありません。基本的にJPAはこのように使用するように設計されていないようです。解決策の1つは、トップレベルプロジェクト(アプリケーション)ごとにonepersistence.xmlを1つだけにすることです。これは、log4j構成に似ています。 persistence.xmlはすべてのクラスをリストする必要があります(<class>)または、Java SEアプリではない場合、jarファイル(<jar-file>)アプリケーションによって使用されます。このようにして、複数のモジュール(jar)のエンティティを単一の永続化ユニットに配置できます。欠点は明らかです。すべてを1つのファイルにリストする必要があります。

編集:私は(おそらく)XMLマッピングファイルを使用する別のソリューションを見つけました、ここでそれをチェックしてください: 複数のjar、単一の永続性ユニットソリューション?

3
Adam Dyga

この概念を使用できます: https://wiki.Eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
   <persistence-unit name="mamcaPU" transaction-type="JTA">
        <provider>org.Eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>mamcaPU</jta-data-source>
        <mapping-file>/META-INF/common-layer-mappings.xml</mapping-file>
    </persistence-unit>
</persistence>

common-layer-mappings.xml

<entity-mappings>   
   <entity class="vub.be.mamca.entity.Surveyactorgrouptable"></entity>
   <entity class="vub.be.mamca.entity.Userevaluationelicitationtable"></entity>
   <entity class="vub.be.mamca.entity.Userevaluationtable"></entity>
   <entity class="vub.be.mamca.entity.Usertable"></entity>
   <entity class="vub.be.mamca.entity.Userweightelicitationtable"></entity>
</entity-mappings>
1
Tunde Pizzle

同様の問題があり、Hibernateの Integrator SPIで 解決した です。

@Override
public void integrate(Configuration configuration,
    SessionFactoryImplementor sessionFactory,
    SessionFactoryServiceRegistry serviceRegistry) {

    configuration.addAnnotatedClass(MyEntity.class);
    configuration.buildMappings();
}

インテグレーターは Javaサービス として提供されます。

0
Markus Malkusch

重複する可能性があります。 my SO question を参照してください。

同じ問題に直面し、見つけた唯一の方法は、すべてのエンティティを最終的な(Web)アプリケーションの1つのpersistence.xmlに蓄積することでした。

同時に、テストリソースで個別のpersistence.xmlファイルを定義して、モジュールごとに受け入れテストを実行できるようにします。

0
Pete