デプロイメントに関する規約には,コンテナ側の責任とJPAプロバイダ側の責任があります。
デプロイメント時に,コンテナはアプリケーション内の決められた場所にパッケージングされたpersistence.xmlを検索します。アプリケーション内にpersistence.xmlが存在する場合には,コンテナはpersistence.xmlに定義された永続化ユニットの定義を処理します。なお,コンテナが検索する場所については,「5.8 persistence.xmlでの定義」を参照してください。
コンテナはpersistence.xmlファイルをpersistence_1_0.xsdで検証します。検証の結果,エラーが発生した場合にはユーザに通知します。persistence.xmlにプロバイダやデータソースの情報が指定されていない場合には,デフォルト値が使用されます。使用されるデフォルト値については,「5.8 persistence.xmlでの定義」を参照してください。コンテナが永続化ユニットのエンティティマネージャファクトリを作成するときには,JPAプロバイダにプロパティを渡すことがあります。
コンテナは,persistence.xmlで永続化ユニットごとに定義されたjavax.persistence.spi.PersistenceProviderの実装クラスのインスタンスを作成し,createContainerEntityManagerFactoryメソッドを呼び出して,コンテナ管理のエンティティマネージャを作成するためのEntityManagerFactoryを取得します。永続化ユニットのメタデータは,PersistenceUnitInfoオブジェクトとして,createContainerEntityManagerFactoryメソッドの引数でJPAプロバイダに渡されます。コンテナは一つの永続化ユニット定義に対して,一つだけEntityManagerFactoryを作成し,そのEntityManagerFactoryから複数のEntityManagerを作成します。
永続化ユニットが再デプロイされる場合には,コンテナはすでに取得したEntityManagerFactoryのcloseメソッドを呼び出したあと,createContainerEntityManagerFactoryを新しいPersistenceUnitInfoとともに呼び出します。
JPAプロバイダはPersistenceProvider SPIを実装し,PersistenceProviderのcreateContainerEntityManagerFactoryメソッドが呼ばれたときに,引数で渡される永続化ユニットのメタデータ(PersisetnceUnitInfo)を使用して,EntityManagerFactoryを作成し,コンテナに返す必要があります。
JPAプロバイダは,永続化ユニットに含まれるマネージドクラス(エンティティクラスなど)のメタデータアノテーションを処理します。また,永続化ユニットでO/Rマッピングファイルが使用されている場合には,JPAプロバイダが解釈する必要があります。このとき,O/Rマッピングファイルをorm_1_0.xsdを使用して検証し,エラーが発生した場合はユーザに通知する必要があります。
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);
}
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();
}