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を作成し、プログラムでクラスを追加する方法はありますか?EntityManagerFactory
に追加できますか?更新:org.hibernate.ejb.Ejb3Configuration
で見つけた:
public Ejb3Configuration configure(String persistenceUnitName, Map integration)
それを解決する方法はいくつかあります。
persistence.xmlで<class>要素が必要ですか? で説明されているように、hibernate.archive.autodetection
プロパティとHibernateは、クラスパスからすべての注釈付きクラスを検索できるはずです。ただし、これはJPA仕様に準拠していません。
Spring 3.1.2(またはおそらく少し前)のSpringをLocalContainerEntityManagerFactoryBean
で使用している場合は、packageToScan
を定義して、LocalContainerEntityManagerFactoryBean
にクラスパスでスキャンするように要求できます。すべての注釈付きクラスを検索します。繰り返しますが、JPA仕様に準拠していません。
Mavenをビルドツールとして使用していました。何年も前に、ビルドプロセス中にpersistence.xmlを生成する小さなプラグインを作成しました。プラグインは、ビルドクラスパスからスキャンしてすべての注釈付きクラスを見つけ、生成されたpersistence.xmlにリストします。これは最も面倒ですが、結果はJPA仕様に準拠しています。 1つの欠点(ほとんどの人には当てはまらない)は、実行時ではなくビルド時にルックアップが発生することです。つまり、エンティティJARがデプロイ時または実行時にのみ提供され、ビルド時には提供されないアプリケーションがある場合、このアプローチは機能しません。
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>
です。
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>
私は同じ問題を経験しましたが、残念ながら簡単な解決策はありません。基本的にJPAはこのように使用するように設計されていないようです。解決策の1つは、トップレベルプロジェクト(アプリケーション)ごとにonepersistence.xmlを1つだけにすることです。これは、log4j構成に似ています。 persistence.xmlはすべてのクラスをリストする必要があります(<class>
)または、Java SEアプリではない場合、jarファイル(<jar-file>
)アプリケーションによって使用されます。このようにして、複数のモジュール(jar)のエンティティを単一の永続化ユニットに配置できます。欠点は明らかです。すべてを1つのファイルにリストする必要があります。
編集:私は(おそらく)XMLマッピングファイルを使用する別のソリューションを見つけました、ここでそれをチェックしてください: 複数のjar、単一の永続性ユニットソリューション?
この概念を使用できます: 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>
同様の問題があり、Hibernateの Integrator
SPIで 解決した です。
@Override
public void integrate(Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
configuration.addAnnotatedClass(MyEntity.class);
configuration.buildMappings();
}
インテグレーターは Javaサービス として提供されます。
重複する可能性があります。 my SO question を参照してください。
同じ問題に直面し、見つけた唯一の方法は、すべてのエンティティを最終的な(Web)アプリケーションの1つのpersistence.xmlに蓄積することでした。
同時に、テストリソースで個別のpersistence.xmlファイルを定義して、モジュールごとに受け入れテストを実行できるようにします。