非常に単純な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
クラスをスキャンする自動メカニズムはありますか?
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>
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
です。 EclipseLink と Toplink の両方が、私が知る限りこれをサポートしています。ただし、前述のように、仕様に従って、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>
Persistence.xmlにClass要素が必要ですか?
いいえ、必ずしもそうとは限りません。 Eclipseでの実行方法は次のとおりです(ケプラーテスト済み)。
プロジェクトを右クリックし、Propertiesをクリックして、JPAを選択します。Persistence class management tick アノテーション付きクラスを自動的に検出。
バージョン3.1以降のJPAをSpringで実行している場合は、packagesToScan
の下にLocalContainerEntityManagerFactoryBean
プロパティを設定し、persistence.xmlを完全に削除できます。
Hibernateは<exclude-unlisted-classes>false</exclude-unlisted-classes>
をSEでサポートしていません(これはTopLinkおよびEclipseLinkで動作することを述べた別のポスター)。
クラスのリストをpersistence.xmlに自動生成するツールがあります。 IntelliJのデータベーススキーマのインポートウィザード。 persistence.xmlでプロジェクトの初期クラスを取得したら、プロジェクトの進行に合わせて手動で単一のクラスを簡単に追加/削除する必要があります。
コンパイルされたクラスを含むフォルダーへのjar-file
要素パスを提供できます。たとえば、persistence.xmlをいくつかの統合テストに準備したときに、そのようなものを追加しました。
<jar-file>file:../target/classes</jar-file>
jPA 2+の場合、これはトリックを行います
<jar-file></jar-file>
戦争中のすべてのjarでアノテーション付き@Entityクラスをスキャンします
あなたが私がやっていることに似ているかどうかはわかりませんが、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"/>
これは解決策ではなく、Springを使用している人へのヒントです。
persistenceXmlLocation
を設定してorg.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
を使用しようとしましたが、これでは<class>
要素を提供する必要がありました(persistenceXmlLocation
がMETA-INF/persistence.xml
を指している場合でも)。
notを使用してpersistenceXmlLocation
を使用すると、これらの<class>
要素を省略できます。
このソリューションが仕様の下にあるかどうかはわかりませんが、他の人と共有できると思います。
エンティティクラスのみが含まれます。いいえMETA-INF/persistence.xml
。
my-entities
に依存します。 EJBのみが含まれます。
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>
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>
必ずしもすべての場合において。
Jboss 7.0.8およびEclipselink 2.7.0を使用しています。 persistence.xmlに同じものを追加せずにエンティティをロードする私の場合、Jboss Standalone XMLに次のシステムプロパティを追加しました。
<property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>