付録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メソッドが呼ばれたときに,引数で渡される永続化ユニットのメタデータ(PersistenceUnitInfo)を使用して,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も定義されていない場合
-