付録F.2 デプロイメントに関する規約
デプロイメントに関する規約には,コンテナ側の責任とJPAプロバイダ側の責任があります。
- 〈この項の構成〉
(1) コンテナ側の責任
デプロイメント時に,コンテナはアプリケーション内の決められた場所にパッケージングされたpersistence.xmlを検索します。アプリケーション内にpersistence.xmlが存在する場合には,コンテナはpersistence.xmlに定義された永続化ユニットの定義を処理します。なお,コンテナが検索する場所については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「5.8 persistence.xmlでの定義」を参照してください。
コンテナはpersistence.xmlファイルをpersistence_1_0.xsdで検証します。検証の結果,エラーが発生した場合にはユーザに通知します。persistence.xmlにプロバイダやデータソースの情報が指定されていない場合には,デフォルト値が使用されます。使用されるデフォルト値は次のとおりです。
-
<provider>タグ
簡易構築定義ファイルで指定したデフォルトのJPAプロバイダが使用されます。また,このタグを省略した場合で,簡易構築定義ファイルでデフォルトのJPAプロバイダが指定されていないときには,JPAプロバイダとしてCJPAプロバイダが使用されます。
- ポイント
-
簡易構築定義ファイルでデフォルトのJPAプロバイダを指定するには,論理J2EEサーバの<param-name>タグにejbserver.jpa.defaultProviderClassNameを指定して,<param-value>タグにデフォルトのJPAプロバイダクラス名を指定します。
なお,簡易構築定義ファイルで,論理J2EEサーバの<param-name>タグにejbserver.jpa.overrideProviderパラメタが指定されているときは,ejbserver.jpa.overrideProviderパラメタの<param-value>タグに指定されているJPAプロバイダクラス名が,<provider>タグやejbserver.jpa.defaultProviderClassNameパラメタに指定した値よりも優先して使用されます。
簡易構築定義ファイルに指定するパラメタについては,「11.2.1 J2EEサーバ用ユーザプロパティを設定するパラメタ」を参照してください。
永続化ユニットで使用されるJPAプロバイダを決定する優先順位を次の表に示します。
表F‒1 永続化ユニットで使用されるJPAプロバイダを決定する優先順位 優先度
使用するJPAプロバイダ
1
簡易構築定義ファイルのejbserver.jpa.overrideProviderプロパティに指定された値
2
persistence.xmlの<provider>タグに指定された値
3
CJPAプロバイダ
(簡易構築定義ファイルのejbserver.jpa.defaultProviderClassNameパラメタを使用して変更することもできる)
-
<jta-data-source>タグ,<non-jta-data-source>タグ
簡易構築定義ファイルのejbserver.jpa.defaultJtaDsNameパラメタまたはejbserver.jpa.defaultNonJtaDsNameパラメタに指定した値が使用されます。ただし,これらのプロパティにはデフォルト値がありません。
ejbserver.jpa.overrideJtaDsNameパラメタまたはejbserver.jpa.overrideNonJtaDsNameパラメタに値が指定されている場合は,<jta-data-source>タグ,<non-jta-data-source>タグに指定された値や,ejbserver.jpa.defaultJtaDsNameパラメタ,ejbserver.jpa.defaultNonJtaDsNameパラメタに指定された値よりも優先して使用されます。
永続化ユニットで使用されるJTAデータソースおよび非JTAデータソースを決定するときの優先順位を次の表に示します。
表F‒2 永続化ユニットで使用されるJTA データソースおよび非JTAデータソースを決定する優先順位 優先度
使用するJPAプロバイダ
1
簡易構築定義ファイルのejbserver.jpa.overrideJtaDsNameプロパティまたはejbserver.jpa.overrideNonJtaDsNameプロパティに指定された値
2
persistence.xml の<jta-data-source>または<non-jta-data-source>エレメントに指定された値
3
簡易構築定義ファイルのejbserver.jpa.defaultJtaDsNameプロパティまたはejbserver.jpa.defaultNonJtaDsNameプロパティに指定した値
コンテナが永続化ユニットのエンティティマネージャファクトリを作成するときには,JPAプロバイダにプロパティを渡すことがあります。
コンテナは,persistence.xmlで永続化ユニットごとに定義されたjavax.persistence.spi.PersistenceProviderの実装クラスのインスタンスを作成し,createContainerEntityManagerFactoryメソッドを呼び出して,コンテナ管理のエンティティマネージャを作成するためのEntityManagerFactoryを取得します。永続化ユニットのメタデータは,PersistenceUnitInfoオブジェクトとして,createContainerEntityManagerFactoryメソッドの引数でJPAプロバイダに渡されます。コンテナは一つの永続化ユニット定義に対して,一つだけEntityManagerFactoryを作成し,そのEntityManagerFactoryから複数のEntityManagerを作成します。
永続化ユニットが再デプロイされる場合には,コンテナはすでに取得したEntityManagerFactoryのcloseメソッドを呼び出したあと,createContainerEntityManagerFactoryを新しいPersistenceUnitInfoとともに呼び出します。
(2) JPAプロバイダ側の責任
JPAプロバイダはPersistenceProvider SPIを実装し,PersistenceProviderのcreateContainerEntityManagerFactoryメソッドが呼ばれたときに,引数で渡される永続化ユニットのメタデータ(PersisetnceUnitInfo)を使用して,EntityManagerFactoryを作成し,コンテナに返す必要があります。
JPAプロバイダは,永続化ユニットに含まれるマネージドクラス(エンティティクラスなど)のメタデータアノテーションを処理します。また,永続化ユニットでO/Rマッピングファイルが使用されている場合には,JPAプロバイダが解釈する必要があります。このとき,O/Rマッピングファイルをorm_1_0.xsdを使用して検証し,エラーが発生した場合はユーザに通知する必要があります。
(3) javax.persistence.spi.PersistenceProviderインタフェース
JPAプロバイダは,javax.persistence.spi.PersistenceProviderインタフェースを実装する必要があります。このインタフェースはコンテナによって呼び出されるものであり,アプリケーションから呼び出すものではありません。PersistenceProviderの実装クラスは,publicで引数のないコンストラクタを持っている必要があります。
javax.persistence.spi.PersistenceProviderインタフェースを次に示します。
package javax.persistence.spi; /** * JPAプロバイダによって実装されるインタフェースです。 * このインタフェースはEntityManagerFactoryを作成するために使用されます。 * Java EE環境ではコンテナによって呼び出され, * JavaSE環境ではPersistenceクラスによって呼び出されます。 */ public interface PersistenceProvider { /** * PersistenceクラスがEntityManagerFactoryを作成する時に呼び出されます。 * * @param emName 永続化ユニットの名前 * @param map JPAプロバイダによって使用されるプロパティのMap。 * ここに指定されたプロパティは,persistence.xmlファイルの対応する * プロパティを上書きするため,またはpersistence.xmlファイルに * 指定されていないプロパティを指定するために使用されます。 *(プロパティを指定する必要がない場合はnullが渡されます) * @return 永続化ユニットのEntityManagerFactory * JPAプロバイダが正しくない場合は,nullを返します。 */ public EntityManagerFactory createEntityManagerFactory(String emName, Map map); /** * コンテナがEntityManagerFactoryを作成する時に呼びだされます。 * * @param info JPAプロバイダが使用するためのメタデータ * @param map JPAプロバイダが使用するためのインテグレーションレベルの * プロパティ(指定しない場合はnullが渡されます) * @return メタデータで指定された永続化ユニットのEntityManagerFactory */ public EntityManagerFactory createContainerEntityManagerFactory( PersistenceUnitInfo info, Map map); }
(4) javax.persistence.spi.PersistenceUnitInfoインタフェース
javax.persistence.spi.PersistenceUnitInfoインタフェースの定義を次に示します。
import javax.sql.DataSource; /** * このインタフェースはコンテナによって実装され, * EntityManagerFactoryを作成する時にJPAプロバイダに渡されて使用される。 */ public interface PersistenceUnitInfo { /** * @return persistence.xmlで定義された永続化ユニット名 */ public String getPersistenceUnitName(); /** * @return persistence.xmlの<provider>エレメントに定義された, * JPAプロバイダ実装クラスの完全修飾クラス名 */ public String getPersistenceProviderClassName(); /** * @return EntityManagerFactoryによって作成されるEntityManagerの * トランザクションのタイプを返す。 * persistence.xmlのtransaction-type属性に指定されたタイプである。 */ public PersistenceUnitTransactionType getTransactionType(); /** * @return JPAプロバイダが使用するためのJTAが有効な * データソースを返す。 * persistence.xmlの<jta-data-source>エレメントで指定されたデータソースか, * デプロイメント時にコンテナによって決定されたデータソースである。 */ public DataSource getJtaDataSource(); /** * @return JPAプロバイダがJTAトランザクションの外で * データにアクセスするための,JTAが無効なデータソースを返す。 * persistence.xmlの<non-jta-data-source>エレメントで指定された * データソースか,デプロイメント時にコンテナによって決定された * データソースである。 */ public DataSource getNonJtaDataSource(); /** * @return JPAプロバイダがエンティティクラスのマッピングを * 決定するためにロードする必要のある,マッピングファイル名のリスト * マッピングファイルは,標準的なXML形式のマッピングフォーマット * でなければならない。 * 一意の名前を持ち,アプリケーションのクラスパスからリソースとして * ロードできるものでなければならない。 * それぞれのマッピングファイル名は,persistence.xmlの<mapping-file>タグ * に指定されたものである。 */ public List<String> getMappingFileNames(); /** * JPAプロバイダが,永続化ユニットのマネージドクラスを検索する必要のある, * JARファイルまたはJARファイルを展開したディレクトリのURLのリストを返す。 * それぞれのURLはpersistence.xmlファイルの<jar-file>タグに指定された * ものである。 * URLはJARファイルまたはJARファイルを展開したディレクトリを指す * ファイルURLか,またはJARのフォーマットのInputStreamを取得できる * そのほかのURL形式である。 * * @return JARファイルまたはディレクトリを指すURLオブジェクトのリスト */ public List<URL> getJarFileUrls(); /** * 永続化ユニットルートであるJARファイルまたはディレクトリのURLを返す。 * (永続化ユニットルートがWEB-INF/classesディレクトリである場合, * WEB-INF/classesディレクトリのURLを返す) * URLはJARファイルまたはJARファイルを展開したディレクトリを指す * ファイルURLか,またはJARのフォーマットのInputStreamを取得できる * そのほかのURL形式である。 * * @return JARファイルまたはディレクトリを指すURLオブジェクト */ public URL getPersistenceUnitRootUrl(); /** * @return JPAプロバイダがマネージドクラスとして扱わなくてはならない * クラス名のリスト。 * それぞれのクラス名はpersistence.xmlファイルの<class>タグに指定された * ものである。 */ public List<String> getManagedClassNames(); /** * @return 永続化ユニットルートに配置されていて, * 明示的にマネージドクラスであると指定されていないクラスを, * マネージドクラスとして扱うかどうかを返す。 * この値は,persistence.xmlファイルの<exclude-unlisted-classes>タグに * 指定されたものである。 */ public boolean excludeUnlistedClasses(); /** * @return Propertiesオブジェクト。 * それぞれのプロパティはpersistence.xmlファイルの<property>タグに * 指定されたものである。 */ public Properties getProperties(); /** * @return JPAプロバイダがクラスやリソースをロードしたり, * URLをオープンしたりするために使用できるClassLoader。 */ public ClassLoader getClassLoader(); /** * PersistenceUnitInfo.getClassLoaderメソッドによって返されるクラスローダで, * 新しいクラスの定義や,クラスの再定義のたびに呼ばれる, * JPAプロバイダのトランスフォーマーを登録する。 * このトランスフォーマーは,PersistenceUnitInfo.getNewTempClassLoaderメソッドで返される * クラスローダでロードされるクラスには影響を与えない。 * クラスローディングのスコープ内で永続化ユニットが幾つ定義されていても, * 同じクラスローディングのスコープ内でクラスが変換されるのは一度だけである。 * * @param transformer コンテナがクラスの定義(再定義)時に呼び出す, * JPAプロバイダのトランスフォーマー */ public void addTransformer(ClassTransformer transformer); /** * JPAプロバイダが一時的にクラスやリソースをロードしたり, * URLをオープンしたりするために使用できるクラスローダの * 新しいインスタンスを返す。 * このクラスローダのスコープやクラスパスは, * PersistenceUnitInfo.getClassLoaderで返される * クラスローダと完全に同じである。 * このクラスローダでロードしたクラスが, * アプリケーションのコンポーネントから参照できるようになることはない。 * JPAプロバイダは,createContainerEntityManagerFactoryの * 呼び出しの延長でだけ,このクラスローダを使用できる。 * * @return 現在のクラスローダと同じスコープ・クラスパスを持つ一時的な * クラスローダ */ public ClassLoader getNewTempClassLoader(); }
- 参考
-
アプリケーションサーバでは,永続化ユニットでJTAデータソース,非JTAデータソースが定義されていない場合には,getJtaDataSource()またはgetNonJtaDataSource()はnullを返します。永続化ユニットでJTAデータソース,非JTAデータソースが定義されていない場合とは,次の状態を指します。
-
persistence.xmlで<jta-data-source>,<non-jta-data-source>が省略されていて,かつデフォルト値がシステムプロパティejbserver.jpa.defaultJtaDsName,ejbserver.jpa.defaultNonJtaDsNameで定義されていない場合
-
システムプロパティejbserver.jpa.overrideJtaDsName,ejbserver.jpa.overrideNonJtaDsNameも定義されていない場合
-