3 永続性ユニットの理解
この章では、永続性ユニットおよび永続層について詳細に説明します。
永続性ユニットについて
永続性ユニットでは、エンティティ・マネージャを取得する際に必要な詳細を定義します。
EclipseLink JPAアプリケーションをパッケージ化するには、persistence.xml
ファイルの作成時に永続性ユニットを構成する必要があります。各永続性ユニットは、persistence.xml
ファイルのpersistence-unit要素で定義します。
persistence.xml
ファイルを使用して、エンティティをパッケージ化します。パッケージ化戦略を選択したら、任意のアーカイブのMETA-INF
ディレクトリにpersistence.xml
ファイルを配置します。次の項では、永続性ユニットの指定方法の詳細について説明します。詳細および例は、JPA仕様の「persistence.xml file」を参照してください。persistence.xml
ファイルに対するEclipseLinkの拡張機能の詳細は、『Java Persistence API (JPA) Extensions Reference for EclipseLink』の「Persistence Property Extensions Reference」を参照してください。
永続性ユニット名について
永続性ユニット名は各モジュール内で一意である必要があります。
Java EE環境でアプリケーションを開発する場合、永続性ユニット名が各モジュール内で一意であることを確認してください。たとえば、emp_ejb.jar
ファイル内で定義できるEmployeeServiceという名前の永続性ユニットは、1つのみです。
詳細は、JPA仕様の「name」を参照してください。
永続性プロバイダについて
永続性プロバイダでは、JPAの実装を定義します。
永続性プロバイダは、persistence.xml
ファイルのprovider要素に定義されています。永続性プロバイダはベンダー固有のものです。EclipseLinkの永続性プロバイダはorg.eclipse.persistence.jpa.PersistenceProviderです。
トランザクション・タイプ・データ・ソースについて
デフォルトのトランザクション・タイプは、データ・ソースと環境によって異なります。
Java EE環境でアプリケーションを開発する場合、デフォルトのトランザクション・タイプであるJTA (Java Transaction API用)を使用し、jta-data-source要素にデータ・ソースを指定します。
JTAに適合しないデータ・ソースを使用する場合は、transaction-type要素にRESOURCE_LOCALを設定して、non-jta-data-source要素に値を指定します。
デフォルトの永続性プロバイダorg.eclipse.persistence.jpa.PersistenceProviderを使用している場合は、接続メタデータに基づいて、プロバイダがデータベース・タイプの自動検出を試みます。このデータベース・タイプを使用して、検出されたデータベース・タイプに固有のSQL文が発行されます。オプションのeclipselink.target-databaseプロパティを指定すれば、データベース・タイプが正しいことを保証できます。
詳細は、JPA仕様の「transaction-type」および「provider」を参照してください。
ロギングについて
ロギングはJPA仕様の一部ではありませんが、EclipseLinkにはロギング・ユーティリティが用意されています。
ログで提供される情報はEclipseLink JPA固有のものです。EclipseLinkでロギングを有効にすれば、次の情報を確認できます。
-
構成の詳細
-
デバッグを容易にするための情報
-
データベースに送信されるSQL
ロギングはpersistence.xml
ファイルに指定できます。EclipseLinkのロギング・プロパティでは、ロギングのレベル、およびログの出力をファイルまたは標準出力のどちらにするかを指定できます。ロギング・ユーティリティはjava.util.loggingに基づいているので、使用するロギング・レベルを指定できます。
ロギング・ユーティリティには、ログ出力の量および詳細度を制御するロギング・レベルが9種類用意されています。ロギング・レベルは、次のようにeclipselink.logging.levelを使用して設定します。
<property name="eclipselink.logging.level" value="FINE"/>
デフォルトでは、System.outまたはコンソールにログが出力されます。出力がファイルにロギングされるように構成するには、eclipselink.logging.file
プロパティを次のように設定します。
<property name="eclipselink.logging.file" value="output.log"/>
EclipseLinkのロギング・ユーティリティはプラガブルで、java.util.loggingなどの数種類のロギング統合がサポートされています。java.util.loggingを有効にするには、eclipselink.logging.loggerプロパティを次のように設定します。
<property name="eclipselink.logging.logger" value="JavaLogger"/>
EclipseLinkでのロギングおよびロギング・ユーティリティで利用可能なロギング・レベルの詳細は、『Java Persistence API (JPA) Extensions Reference for EclipseLink』の「Persistence Property Extensions Reference」を参照してください。
ベンダー・プロパティについて
persistence.xml
ファイルの最後のセクションは、propertiesセクションです。
properties要素によって、永続性ユニットに対してEclipseLink永続性プロバイダ固有の設定を指定できます。JPA仕様の「properties」を参照してください。『Java Persistence API (JPA) Extensions Reference for EclipseLink』の「Persistence Property Extensions Reference」も参照してください。
マッピング・ファイルについて
このメタデータは、すべてのマッピング・ファイルと注釈の集合です(xml-mapping-metadata-complete要素が存在しない場合)。
永続性ユニットにメタデータを適用します。メタデータに対して1つのマッピングorm.xml
ファイルを使用し、そのファイルをクラスパスのMETA-INF
ディレクトリに配置する場合、それを明示的にリストする必要はありません。このファイルは、EclipseLink永続性プロバイダによって自動的に検索され、使用されます。マッピング・ファイルを別の方法で指定する場合、または別の場所に配置する場合、それらをpersistence.xmlファイルのmapping-file要素にリストする必要があります。
詳細は、JPA仕様の「mapping-file, jar-file, class, exclude-unlisted-classes」を参照してください。
管理対象クラスについて
すべてのエンティティおよび他の管理対象クラスは、単一のJARファイルと、META-INFディレクトリのpersistence.xmlファイルおよび1つ以上のマッピング・ファイルに配置します(XMLにメタデータを格納する場合)。
EclipseLink永続性プロバイダは、永続性ユニットを処理するときに、特定の各永続性ユニットで管理するエンティティ、マップ済スーパークラス、埋込みオブジェクトおよびコンバータのセットを特定します。
EclipseLink永続性プロバイダは、デプロイ時に、次のいずれかのソースから管理対象クラスを取得できます。管理対象クラスは、次のいずれかである場合に含まれます。
-
ローカル・クラス: persistence.xmlファイルがパッケージ化されているデプロイメント・ユニットの@Entity、@MappedSuperclass、@Embeddableまたは@Converter注釈付きのクラス。詳細は、JPA仕様の「Entity」を参照してください。
注意:
アプリケーションをJava EE環境にデプロイする場合、EclipseLink永続性プロバイダではなくアプリケーション・サーバー自体によってローカル・クラスが検出されます。Java SE環境で、exclude-unlisted-classes要素をfalseに設定すると、この機能を有効化できます(この要素をfalseに設定すると、EclipseLink永続性プロバイダによってローカル・クラスの検出が試行されます)。JPA仕様の「mapping-file, jar-file, class, exclude-unlisted-classes」を参照してください。
-
マッピング・ファイルのクラス: XMLマッピング・ファイルのentity (JPA仕様の「entity」を参照)、mapped-superclass、embeddableなどのマッピング・エントリを持つクラス。詳細は、JPA仕様の「mapped-superclass」および「embeddable」を参照してください。
デプロイされたコンポーネント・アーカイブにこれらのクラスが含まれる場合、それらはすでにクラスパスに存在します。存在しない場合、それらを明示的にクラスパスに含める必要があります。
-
明示的にリストされたクラス: persistence.xmlファイルにclass要素としてリストされているクラス。
次のいずれかの場合、クラスを明示的にリストすることを検討してください。
-
デプロイメント・ユニットのJARにローカルではない追加クラスが存在する場合。たとえば、永続性ユニットのエンティティで使用する異なるJARに埋込みオブジェクト・クラスが存在する場合です。この場合、persitence.xmlファイルのclass要素に完全修飾されたクラスをリストします。また、クラスを含むJARまたはディレクトリが、デプロイ済のコンポーネントのクラスパスに含まれることを確認する必要があります(たとえば、デプロイメントJARのマニフェスト・クラスパスにそれを追加します)。
-
エンティティとして注釈を付けることのできる1つ以上のクラスを除外する場合。クラスに@Entity注釈を付けることができても、デプロイされた特定のコンテキストでそれをエンティティとして扱いません。たとえば、特定のエンティティを転送オブジェクトとして使用し、デプロイメント・ユニットの一部にする必要がある場合です。この場合、Java EE環境で、persistence.xmlファイルのexclude-unlisted-classes要素を使用する必要があります(この要素のデフォルト設定の使用によって、ローカル・クラスが永続性ユニットに追加されなくなります)。詳細は、JPA仕様の「mapping-file, jar-file, class, exclude-unlisted-classes」を参照してください。
-
アプリケーションをJava SE環境で実行する予定で、Java SEでそれ以外に移植可能な方法がないため、クラスを明示的にリストする場合。
-
-
管理対象クラスの追加のJARファイル:
persistence.xml
ファイルのjar-file要素にリストされている名前付きJARファイルの注釈付きクラス。詳細は、JPA仕様の「mapping-file, jar-file, class, exclude-unlisted-classes」を参照してください。jar-file要素にリストされているJARファイルが、デプロイメント・ユニットのクラスパスに含まれることを確認する必要があります。これを行うには、デプロイメント・ユニットのマニフェスト・クラスパスに手動でJARファイルを追加します。
jar-file要素のJARファイルは、
persistence.xml
ファイルが存在しているJARファイルの親を基準としてリストする必要があることに注意してください。これは、マニフェスト・ファイルのクラスパス・エントリに指定する内容と一致します。
デプロイメント・クラスパスについて
EJB JAR、WARまたはEARファイルにアクセスできるようにするには、クラスまたはJARファイルがデプロイメント・クラスパスに含まれる必要があります。
これは次のいずれかの方法で可能になります。
-
JARファイルをEJB JARまたはWARファイルのマニフェスト・クラスパスに配置します。
これを行うには、JARまたはWARファイルの
META-INF/MANIFEST.MF
ファイルにクラスパス・エントリを追加します。空白で区切ることで、1つ以上のディレクトリまたはJARファイルを指定できます。 -
EARファイルのライブラリ・ディレクトリにJARファイルを配置します。
これによって、アプリケーション・クラスパスでJARファイルを使用できるようになり、EARファイル内にデプロイされたすべてのモジュールからアクセス可能になります。デフォルトでは、これはEARファイルのlibディレクトリになりますが、
application.xml
デプロイメント・ディスクリプタのlibrary-directory要素を使用して、EARファイルの任意のディレクトリとなるように構成できます。
永続性ユニットのパッケージ・オプションについて
Java EEでは、様々なパッケージ構成で永続性がサポートされます。
アプリケーションは、次のモジュール・タイプにデプロイできます。
-
EJBモジュール: エンティティをEJB JARにパッケージ化できます。EJB JARで永続性ユニットを定義する場合、
persistence.xml
ファイルはオプションではなく、それを作成してデプロイメント・ディスクリプタ(存在する場合)とともにJARのMETA-INF
ディレクトリに配置する必要があります。 -
Webモジュール: WARファイルを使用してエンティティをパッケージ化できます。この場合、
WEB-INF/classes/META-INF
ディレクトリにpersistence.xmlファイルを配置します。WARのクラスパスにWEB-INF/classesディレクトリが自動的に含まれるため、そのディレクトリを基準としてマッピング・ファイルを指定します。 -
永続性アーカイブ: 永続性アーカイブは、
META-INF
ディレクトリにpersistence.xml
ファイルを含み、そのpersistence.xml
で定義された永続性ユニットの管理対象クラスを含むJARです。異なるJava EEモジュールの複数のコンポーネントで永続性ユニットを共有するか、それにアクセスする場合、永続性アーカイブを使用します。永続性アーカイブを作成したら、それをEARのルートまたはアプリケーション・ライブラリ・ディレクトリに配置できます。または、永続性アーカイブをWARの
WEB-INF/lib
ディレクトリに配置することもできます。この場合、永続性ユニットにアクセスできるのは、WAR内のクラスのみになりますが、永続性ユニットの定義とWebアーカイブ自体を分離することができます。
詳細は、JPA仕様の「Persistence Unit Packaging」を参照してください。
永続性ユニットの有効範囲について
1つのpersistence.xmlファイルに任意の数の永続性ユニットを定義できます。
次に、定義済およびパッケージ化済の永続性ユニットを使用するためのルールを示します。
-
永続性ユニットには、その定義の有効範囲内でのみアクセス可能です。
-
永続性ユニット名は、その有効範囲内で一意である必要があります。
詳細は、JPA仕様の「Persistence Unit Scope」を参照してください。
コンポジット永続性ユニットについて
コンポジット永続性ユニットを使用すると、(エンティティ・タイプの独自のセットがそれぞれに設定された)複数の永続性ユニットを単一の永続性コンテキストとして公開できます。
このコンポジット永続性ユニットの一部である個々の永続性ユニットを、コンポジット・メンバー永続性ユニットと呼びます。
コンポジット永続性ユニットでは、次のことを行えます。
-
複数の永続性ユニット内の任意のエンティティ間のリレーションシップのマッピング
-
複数のデータベースおよび様々なデータ・ソースにストアされているエンティティへのアクセス
-
エンティティの完全なセット全体に対する問合せおよびトランザクションの容易な実行
次の図は、単純なコンポジット永続性ユニットを示しています。EclipseLinkではpersistence.xmlファイルを処理し、2つのコンポジット・メンバー永続性ユニットを含むコンポジット永続性ユニットを検出します。
-
クラスAは、member1.jarファイルにあるmemberPu1という名前の永続性ユニットによってマップされています。
-
クラスBは、member2.jarファイルにあるmemberPu2という名前の永続性ユニットによってマップされています。
詳細は、『Solutions Guide for EclipseLink』の「Using Multiple Databases with a Composite Persistence Unit」を参照してください。
永続層の構築および使用
EclipseLinkでは、クラスが永続クラスになるには特定の最低要件を満たしている必要があります
EclipseLinkでは、大部分の要件を満たすための代替方法も用意しています。EclipseLinkは、オブジェクト・モデルへの介入を最小限にできるメタデータ・アーキテクチャを使用した、非介入型アプローチを使用します。
トピック
実装オプション
EclipseLinkを使用して永続層を実装する際は、次のオプションを検討してください。
EclipseLink JPAメタデータ、注釈およびXMLの使用
JPAを使用している場合は、標準のJPAの注釈およびpersistence.xml、EclipseLink JPAの注釈の拡張機能およびEclipseLink JPAのpersistence.xmlの拡張機能を任意に組み合せて永続層コンポーネントを指定できます。
詳細は、「構成の基本について」を参照してください。
EclipseLinkメタデータJava APIの使用
永続層コンポーネントは、Javaでコーディングまたは生成できます。Javaコードを使用するには、project、login、platform、descriptorsおよびmappingsなど、プロジェクトの各要素に関して、コードを手動で記述する必要があります。アプリケーションがモデルベースであり、コード生成に強く依存する場合は、これの方が効率的です。
メソッドおよび直接フィールド・アクセスの使用
クラスのフィールド(データ・メンバー)にアクセスする際は、getter/setterメソッドを使用してアクセスするか(プロパティ・アクセスとも呼ばれる)、フィールド自体に直接アクセスできます。
メソッド・アクセスと直接フィールド・アクセスのどちらを使用するかは、アプリケーション設計によって決まります。次のガイドラインを考慮してください。
-
クラス外ではメソッド・アクセスを使用します。
これは、クラスの本来のパブリックAPIです。getter/setterメソッドは、必要なすべての副次的な処理を行うため、クライアントはその詳細を認識する必要がありません。
-
クラス内では、パフォーマンス向上のため直接フィールド・アクセスを使用します。
この場合は、getter/setterメソッドを使用しないために起動されない副次的な処理を考慮に入れる必要があります。
メソッド・アクセスと直接フィールド・アクセスのどちらを使用するかを検討する際は、次の制限を考慮してください。
getter/setterメソッドで変更追跡を有効にした場合(たとえば、メソッドsetPhoneを@ChangeTrackingで修飾した場合)は、クライアントでgetter/setterメソッドを使用してフィールド(phone)を変更すると、EclipseLinkではその変更を追跡します。
同様に、フィールドで変更追跡を有効にした場合(たとえば、フィールドphoneを@ChangeTrackingで修飾した場合)は、クライアントでフィールド(phone)を直接変更すると、EclipseLinkではその変更を追跡します。
ただし、getter/setterメソッドで変更追跡を有効にした場合(たとえば、メソッドsetPhoneを@ChangeTrackingで修飾した場合)でも、クライアントがフィールド(phone)に直接アクセスする場合は、EclipseLinkでは変更を検出しません。クラス内ではパフォーマンス向上のためフィールド・アクセスを、クラス外ではメソッド・アクセスを使用する形式でのコーディングを選択する場合は、この制限に注意してください。
詳細は、『Java Persistence API (JPA) Extensions Reference for EclipseLink』の@ChangeTracking注釈の説明を参照してください。
Javaバイト・コード・ウィービングの使用
ウィービングは、コンパイル済のJavaクラスのバイトコードを操作する方法です。
JPAエンティティとPlain Old Java Object (POJO)クラスの両方のパフォーマンスを向上するために、遅延ロード、変更追跡、フェッチ・グループ、内部最適化などの操作にウィービングを使用します。
詳細は、「ウィービングについて」を参照してください。
永続クラス要件
永続Javaオブジェクトを作成する場合、privateまたはprotected属性で直接アクセスを使用します。
ウィービングを使用している場合、ValueHolderInterface
は必要ありません。詳細は、「ウィービングについて」を参照してください。インダイレクションおよび透過インダイレクションの詳細は、「インダイレクション(遅延ロード)」を参照してください。
永続層コンポーネント
アプリケーションの永続層の目的は、実行時にセッションを使用してマッピング・メタデータとデータ・ソースを関連付け、EclipseLinkのキャッシュ、問合せと式、およびトランザクションを使用して永続オブジェクトの作成、読取り、更新および削除を行うことです。
通常、EclipseLink永続層には次のコンポーネントが含まれます。
マッピング・メタデータ
EclipseLinkアプリケーションのメタデータ・モデルは、プロジェクトに基づいています。プロジェクトは、ディスクリプタ、マッピングおよびランタイム機能をカスタマイズする各種ポリシーで構成されています。セッションからプロジェクトを参照することにより、このマッピングと構成情報を特定のデータ・ソースとアプリケーションに関連付けます。
詳細は、次を参照してください。
キャッシュ
デフォルトでは、EclipseLinkセッションはオブジェクト・アイデンティティを保証するオブジェクトレベルのキャッシュを提供し、アプリケーションがデータ・ソースにアクセスする回数を減らしてパフォーマンスを向上します。EclipseLinkは、ロック、リフレッシュ、無効化、分離およびコーディネーションなどの、様々なキャッシュ・オプションを提供します。キャッシュ・コーディネーションを使用して、デプロイされたアプリケーションの他のインスタンスと変更を同期化するようにEclipseLinkを構成できます。永続性ユニットまたはエンティティ・レベルでほとんどのキャッシュ・オプションを構成できます。また、問合せ単位またはディスクリプタでキャッシュ・オプションを構成して、参照クラスのすべての問合せに適用されるようにできます。
詳細は、「キャッシュの理解」を参照してください。
問合せおよび式
オブジェクト・リレーショナル・アーキテクチャでは、EclipseLinkによって、複数のオブジェクトおよびデータ問合せタイプが提供され、次のように問合せ選択基準の柔軟なオプションを使用できます。
-
EclipseLink式
-
JPQL (Java Persistence Query Language)
-
SQL
-
ストアド・プロシージャ
-
例による問合せ
これらのオプションを使用して、あらゆるタイプの問合せを作成できます。名前付き問合せを使用してアプリケーション問合せを定義することをお薦めします。名前付き問合せは、プロジェクトのメタデータ内に保持され、名前で参照されます。これにより、アプリケーション開発は簡単になり、問合せはカプセル化されてメンテナンス・コストが軽減します。
注意:
これらの問合せ方法は、MOXy (OXM、JAXB)マッピングでは使用できません。ただし、レガシーEIS XMLプロジェクトを使用する場合は、問合せを実行できます。
詳細は、「問合せの理解」および「EclipseLinkの式の理解」を参照してください。
オブジェクトの永続化について
この項では、リレーショナル・マッピングについて簡単に説明し、オブジェクト・モデリングとリレーショナル・モデリングへの手引きとなる情報および制限が提供されます。この情報は、アプリケーションを作成するときに役立ちます。
アプリケーション・オブジェクト・モデル
オブジェクト・モデリングとは、アプリケーション・オブジェクトを表現するJavaクラスを設計することです。
自分で選んだ統合開発環境(IDE)またはUnified Modeling Language (UML)モデリング・ツールを使用して、アプリケーション・オブジェクト・モデルを定義および作成できます。
EclipseLinkデータベース・セッションにディスクリプタを登録するクラスは、すべて永続クラスと呼ばれます。EclipseLinkでは、永続クラスは、データベースに格納されるあらゆるprivateまたはprotected属性に対してpublicアクセッサ・メソッドを提供する必要はありません。詳細は、「永続クラス要件」を参照してください。
データ・ストレージ・スキーマ
データ・ストレージ・スキーマとは、アプリケーションの永続データを編成するために実装する設計のことです。
このスキーマは、永続データ自体を参照するのであって、実際のデータ・ソースを参照するのではありません(例、リレーショナル・データベースや非リレーショナル・レガシー・システム)。
アプリケーション開発プロセスの設計フェーズで、データ・ソースのクラスの実装方法を決定する必要があります。既存のデータ・ソース情報を統合する場合、クラスと既存データの関係を確認する必要があります。統合するレガシー情報がない場合は、各クラスを格納する方法を決定してから必要なスキーマを作成します。
主キーおよびオブジェクト・アイデンティティ
オブジェクトを永続化する場合、各オブジェクトには、格納および取得時にそれを一意に識別するためのアイデンティティが必要です。
オブジェクト・アイデンティティは、一般に一意の主キーを使用して実装されます。このキーは、各オブジェクトを識別し、参照を作成および管理するために、EclipseLinkによって内部的に使用されます。オブジェクト・アイデンティティが損われると、オブジェクト・モデルが破損することがあります。
Javaアプリケーションでは、メモリー内の各オブジェクトが1つのみのオブジェクト・インスタンスによって表される場合にオブジェクト・アイデンティティが維持されます。同じオブジェクトの複数取得は、同一オブジェクトの複数コピーを返すのではなく、同一オブジェクト・インスタンスへの参照を返します。
EclipseLinkは、複数アイデンティティ・マップをサポートして、オブジェクト・アイデンティティを保持します(コンポジット主キーを含む)。詳細は、「キャッシュのタイプとサイズについて」を参照してください。
マッピング
EclipseLinkでは、メタデータを使用して、オブジェクトおよびBeanのデータ・ソースへのマップ方法を記述します。
このアプローチによって、永続性情報とオブジェクト・モデルが分離されるため、開発者は自由に理想的なオブジェクト・モデルを設計し、DBAは自由に理想的なスキーマを設計できます。詳細は、「メタデータについて」を参照してください。
実行時に、EclipseLinkはメタデータを使用して、アプリケーションが必要とするたびにシームレスおよび動的にデータ・ソースと対話します。
EclipseLinkは、オブジェクト・モデルに含まれる可能性のある様々なデータ・タイプと参照をサポートする、広範なマッピング階層を提供します。詳細は、「マッピングの理解」を参照してください。
外部キーとオブジェクト・リレーションシップ
外部キーは、別の表の一意キー(通常は主キー)を参照する1つ以上の列です。
主キーと同様、外部キーは任意の数のフィールドで、これらすべてが1つの単位として扱われます。外部キーと参照先の親である主キーは、フィールドの数およびタイプが同じである必要があります。
外部キーは、1つの表の1つ以上の列から別の表の1つ以上の列へのリレーションシップを表します。たとえば、すべてのEmployee
に属性addressがあり、この属性にAddress(独自のディスクリプタおよび表を所有)のインスタンスが含まれている場合、address属性に対する1対1マッピングにより、特定のEmployee
の住所を見つけるための外部キー情報が指定されます。
継承
オブジェクト指向システムでは、クラスを、他のクラスに基づいて定義できます。
たとえば、オートバイ、セダンおよびバンは、すべて乗り物の種類です。それぞれの乗り物タイプは、Vehicleクラスのサブクラスです。同様に、Vehicleクラスは、特定の各乗り物タイプのスーパークラスです。各サブクラスはそのスーパークラスから属性およびメソッドを継承します(これらにそのクラス独自の属性とメソッドを追加します)。
継承により、次のようなアプリケーションの利点が提供されます。
-
サブクラスを使用することにより、スーパークラスから提供された共通の要素をベースとして特殊化した動作を提供できます。継承を使用することで、スーパークラスのコードが何度も再利用できます。
-
一般的な動作を定義する抽象スーパークラスを実装できます。この抽象スーパークラスは、動作を定義し一部実装できます。詳細については、特殊化したサブクラスを使用して完成します。
同時実行性
同時クライアントを同時にログインさせるには、サーバーが各クライアント用に実行の専用スレッドを生成する必要があります。
これは、Java EEアプリケーション・サーバーによって自動的に行われます。専用スレッドにより、各クライアントは他のクライアントの完了を待たずに作業できるようになります。EclipseLinkは、これらのスレッドがアイデンティティ・マップを変更するときやデータベース・トランザクションを実行する際、互いに干渉しないように保証します。クライアントは、独立したスレッド・セーフな方法でトランザクションを変更できます。EclipseLinkは、変更するオブジェクトのクローンを管理することで、各クライアントの作業を他の同時クライアントおよびスレッドから分離します。これは、本質的に、データベース・トランザクションとしてACID (Atomicity、Consistency、Isolation、Durability)トランザクション方針のすべてを維持する、オブジェクトレベルのトランザクション・メカニズムです。
EclipseLinkでは、オプティミスティックおよびペシミスティック・ロック戦略が構成できるようにサポートされていて、EclipseLink並行性マネージャが使用するロックのタイプをカスタマイズできます。詳細は、「ディスクリプタとロック」を参照してください。
キャッシュ
EclipseLinkキャッシュは、データベースからオブジェクトとして返されたデータを将来の使用のために自動的に保存しておくことにより、アプリケーションのパフォーマンスを向上させます。
このキャッシュにはいくつかの利点があります。
-
データベースから以前に読み取られたJavaオブジェクトを再利用することで、データベース・アクセスが最小限に抑えられます。
-
オブジェクトがキャッシュにすでに存在している場合、データベースへのSQLコールが最小限に抑えられます。
-
データベースへのネットワーク・アクセスが最小限に抑えられます。
-
キャッシュ・ポリシーはクラス単位またはBean単位に設定できます。
-
キャッシュのオプションおよび動作のベースを、Javaガベージ・コレクションにすることができます。
EclipseLinkには、複数のキャッシュ・ポリシーがサポートされているという高い柔軟性があります。開発者は、個々のアプリケーション・パフォーマンスに基づいて、パフォーマンスを最大限にするためにキャッシュを微調整できます。詳細は、「キャッシュの理解」を参照してください。
非介入型の永続性
EclipseLinkの非介入型のアプローチでは、メタデータ・アーキテクチャを通じて永続性を実現するため、オブジェクト・モデルへの介入がほとんどありません。
Javaオブジェクトを永続化する際、EclipseLinkでは次のいずれも不要です。
-
永続スーパークラスまたは永続インタフェースの実装
-
オブジェクト・モデルにおける必要なメソッドの保存、削除またはロード
-
特別な永続メソッド
-
オブジェクト・モデルへのソース・コードの生成またはラップ
この非介入型アプローチの詳細は、「永続層の構築および使用」を参照してください。「メタデータについて」を参照してください。
インダイレクション
インダイレクション・オブジェクトは、アプリケーション・オブジェクトのかわりとなるため、アプリケーション・オブジェクトは必要とされるまでデータベースから読み取られません。
インダイレクション(JPAでの遅延ロード)を使用すると、EclipseLinkで関連オブジェクトのスタンドインを作成できます。これにより、特にアプリケーションが取得したオブジェクトのみのコンテンツを必要とし、そのオブジェクトに関連するすべてのオブジェクトのコンテンツは必要としない場合に、パフォーマンスの大幅な向上が見られます。
注意:
常にインダイレクションを使用することをお薦めします。
EclipseLinkは、プロキシ・インダイレクション、透過インダイレクションおよびValueHolderインダイレクションなど、いくつかのインダイレクション・モデルを提供します。
詳細は、「コレクション・マッピング」および「インダイレクション(遅延ロード)」を参照してください。
可変性
可変性とは、複雑なフィールドのプロパティの1つであり、フィールド値を(置換ではなく)変更できるかどうかを指定します。
不変マッピングでは、オブジェクトのオブジェクトIDが変更されないかぎり、つまり、オブジェクト値が別のオブジェクト値と完全に置換されないかぎり、マップされたオブジェクト値は変更できません。
可変マッピングでは、オブジェクトのオブジェクトIDを変更しなくても、マップされたオブジェクト値を変更できます。
デフォルトでは、EclipseLinkは次のように想定します。
-
すべてのTransformationMappingインスタンスは可変
-
すべてのJPA @Basicマッピング・タイプ(Serializableタイプは除く)は不変(DateおよびCalendarタイプを含む)
-
すべてのJPA @BasicマッピングのSerializableタイプは可変
値が不変か可変かは、アプリケーションによる永続クラスの使用方法に大きく依存します。たとえば、EclipseLinkは、デフォルトでDateタイプの永続フィールドを不変であると想定するため、フィールドの値が同じオブジェクトIDを持つかぎり、その値は変更されていないものとみなされます。アプリケーションでDateクラスのsetメソッドを使用する場合、そのオブジェクトIDを変更せずにDateオブジェクトの値の状態を変更できます。この場合、EclipseLinkでは変更が検出されません。これを回避するには、マッピングを可変として構成し、EclipseLinkに対して、オブジェクトIDのみではなく永続値の状態を調査するように指示します。
可変性を構成できる対象は次のとおりです。
-
TransformationMappingインスタンス
-
各JPA @Basicマッピング・タイプ(DateおよびCalendarタイプを含む)
-
すべてのDateおよびCalendarタイプ
可変性は、変更追跡のパフォーマンスに影響を与える場合があります。たとえば、トランスフォーメーション・マッピングが可変値をマップする場合、EclipseLinkは値をクローニングし、比較する必要があります。マッピングで単純な不変の値をマップする場合は、マッピングを不変として構成すると、パフォーマンスを向上できます。
可変性は、ウィービングにも影響を与えます。EclipseLinkがウィービングを実行できるのは、不変マッピングの属性変更追跡ポリシーのみです。
詳細は、「ウィービングについて」を参照してください。『Java Persistence API (JPA) Extensions Reference for EclipseLink』の@Mutable注釈の説明も参照してください。
EclipseLink永続性マネージャへのアプリケーションの移行
EclipseLinkを永続性マネージャとして使用するように、アプリケーション・サーバーを構成できます。
JARファイルに含まれるコンテナ管理の永続性を備えたすべてのエンティティに対して、ただ1つの永続性マネージャのみを使用できます。
EclipseLinkは、EclipseLinkを永続性マネージャとして使用するように既存のJava EEアプリケーションを移行するための自動サポートを提供します。詳細は、『Solutions Guide for EclipseLink』の「Migrating from Apache OpenJPA to EclipseLink」を参照してください。
ウィービングについて
ウィービングは、コンパイル済のJavaクラスのバイトコードを操作する方法です
EclipseLinkのJPA永続性プロバイダでは、ウィービングを使用してJPAエンティティとPlain Old Java Object (POJO)クラスの両方を拡張し、遅延ロード、変更追跡、フェッチ・グループ、内部最適化などの操作に対応します。
ウィービングは、実行時(エンティティのロード時)に動的に実行するか、エンティティの.classファイルを後処理してコンパイル時に静的に実行できます。デフォルトでは、EclipseLinkは、Java EEアプリケーション・サーバーの内部やJava SE内(EclipseLinkエージェントが構成されている場合)などで、可能なかぎり動的ウィービングを使用します。動的ウィービングは構成しやすく、プロジェクトのビルド・プロセスを変更する必要がないので、動的ウィービングをお薦めします。
動的ウィービングの使用
動的ウィービングを使用すると、アプリケーション・クラス・ファイルを実行時にロードする際に、1つずつウィービングできます。
ウィービングするクラスの数がごく少ないか、クラスのウィービング時間が短い場合、このオプションを検討してください。
ウィービングするクラスの数が多いか、クラスのウィービング時間が長い場合は、静的ウィービングの使用を検討します。
静的ウィービングの使用
静的ウィービングを使用すると、すべてのアプリケーション・クラス・ファイルをビルド時にウィービングして、事前ウィービング済のクラス・ファイルを配信できます。
該当するすべてのクラス・ファイルのウィービングをビルド時に実行し、事前ウィービング済のクラス・ファイルを配信する場合に、このオプションの使用を検討してください。これを実行することで、動的ウィービングで必要とされる実行時のウィービング・ステップを省略して、アプリケーション・パフォーマンスを向上できます。
また、エージェントを構成できないJava環境でウィービングを実行する場合も、静的ウィービングの使用を検討してください。
POJOクラスのウィービング
EclipseLinkでは、ウィービングを実行するPOJOアプリケーションをパッケージ化する際に、作成したJAR内のすべてのPOJOクラスのウィービングを実行します。
EclipseLinkでは、POJOクラスで次の機能を有効にするためにウィービングを使用します。
-
遅延ロード
-
変更追跡
-
フェッチ・グループ
EclipseLinkでは、persistence.xml
ファイルに定義されている次のすべてのクラスのウィービングを実行します。
-
persistence.xml
ファイルにリストしたすべてのクラス -
persistence.xml
ファイルを含むJARに関連するすべてのクラス(要素<exclude-unlisted-classes>がfalseの場合)。
ウィービングとJava EEアプリケーション・サーバー
デフォルトのEclipseLinkのウィービング動作は、EclipseLink JPA永続性プロバイダを使用する、Java EE JPA準拠のアプリケーション・サーバーで適用されます。
この動作を変更するには、persistence.xml
ファイル(JPAエンティティまたはPOJOクラス用)を変更して、EclipseLink JPAプロパティ、EclipseLink JPA注釈、またはその両方を使用します。
永続性ユニット・プロパティを使用したウィービングの無効化
永続性ユニット・プロパティを使用してウィービングを無効にできます。
EclipseLinkの永続性ユニット・プロパティを使用してウィービングを無効化するには、次の1つ以上のプロパティをfalseに設定してpersistence.xml
を構成します。
-
eclipse.weaving: すべてのウィービングを無効化します。
-
eclipselink.weaving.lazy: 遅延ロード(インダイレクション)のウィービングを無効化します。
-
eclipselink.weaving.changetracking: 変更追跡のウィービングを無効化します。
-
eclipselink.weaving.fetchgroups: フェッチ・グループのウィービングを無効化します。
-
eclipselink.weaving.internal: 内部最適化のウィービングを無効化します。
-
eclipselink.weaving.eager: 即時リレーションシップのインダイレクションのウィービングを無効化します。