Fusion Middleware Oracle TopLinkソリューション・ガイド

11g リリース1(11.1.1)

B66616-01(原本部品番号:E25034-02)

目次

タイトルおよび著作権情報

はじめに

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

1 概要

- 1.1 このマニュアルについて

- 1.2 基礎的な必知事項

- 1.3 ユースケース

2 WebLogic ServerでのTopLinkの使用

- 2.1 TopLinkおよびWebLogic Serverの理解

- 2.1.1 WebLogic ServerでTopLinkを使用する利点

- 2.1.2 他のFusion Middleware製品に対するTopLinkの関係

- 2.2 開始時の必要事項

- 2.3 主なタスク

- 2.3.1 タスク1: デフォルトJPAプロバイダとしてTopLinkを設定(WebLogic Server 11g)

- 2.3.2 タスク2: WebLogic Server 11gでJPA 2.0をサポートするためのパッチの適用

- 2.3.3 タスク3: WebLogic ServerのEclipseLinkのバージョンの更新

- 2.3.4 タスク4: WebLogic ServerのJMX MBean拡張の構成

- 2.3.5 タスク5: ロギング統合の使用または再構成

- 2.3.5.1 ロギング統合の動作方法

- 2.3.5.2 管理コンソールでの永続性ユニットのロギング・レベルの表示

- 2.3.5.3 デフォルト・ロギング統合のオーバーライド

- 2.3.5.4 TopLinkのロギングを公開するためのWebLogic Serverの構成

- 2.3.5.5 その他の考慮事項

- 2.3.6 タスク6: TopLinkを使用した、Javaアプリケーションへの永続性の追加

- 2.3.7 タスク7: データ・ソースの構成

- 2.3.7.1 JPAアプリケーションのデータ・ソースを構成する方法

- 2.3.7.2 グローバル・スコープのJTAデータ・ソースの構成

- 2.3.7.3 アプリケーション・スコープのJTAデータ・ソースの構成

- 2.3.7.4 非JTAデータ・ソースの構成およびアプリケーションのトランザクション管理

- 2.3.7.5 設定の一致の確認

- 2.3.8 タスク8: Oracleデータベースの高度な機能を使用するためのドメインの拡張

- 2.3.9 タスク10: WebLogic Serverの起動とアプリケーションのデプロイ

- 2.3.10 タスク11: アプリケーションの実行

- 2.3.11 タスク12: WebLogic Serverの永続性設定の構成および監視

- 2.4 その他の参考資料

- 2.4.1 コード・サンプル

- 2.4.2 関連Javadoc

3 GlassFish ServerでのTopLinkの使用

- 3.1 TopLinkおよびGlassFish Serverの理解

- 3.1.1 GlassFish ServerでTopLinkを使用する利点

- 3.1.2 Fusion Middleware製品に対するGlassFish ServerとTopLinkの関係

- 3.2 開始時の必要事項

- 3.3 主なタスク

- 3.3.1 タスク1: GlassFish Serverに対するObject-XML (JAXB)サポートの追加(オプション)

- 3.3.2 タスク2: データソースの設定

- 3.3.2.1 GlassFish ServerへのOracleデータベースのJDBCドライバの統合

- 3.3.2.2 リソースに対するJDBC接続プールの作成

- 3.3.2.3 JDBCリソースの作成

- 3.3.3 タスク3: persistence.xmlファイルの作成

- 3.3.3.1 永続性プロバイダの指定

- 3.3.3.2 Oracleデータベースの指定

- 3.3.3.3 ロギングの指定

- 3.3.4 タスク4: JPA用のGlassFish Serverの設定

- 3.3.5 タスク5: アプリケーションの作成

- 3.3.6 タスク6: GlassFish Serverに対するアプリケーションのデプロイ

- 3.3.7 タスク7: アプリケーションの実行

- 3.3.8 タスク8: アプリケーションの監視

- 3.4 その他の参考資料

4 コンポジット永続性ユニットによる複数データベースの使用

- 4.1 コンポジット永続性ユニットの理解

- 4.1.1 コンポジット永続性ユニットの要件

- 4.2 主なタスク

- 4.2.1 タスク1: コンポジット永続性ユニットの構成

- 4.2.2 タスク2: コンポジット永続性ユニットの使用

- 4.2.3 タスク3: コンポジット永続性ユニットのデプロイ

- 4.3 その他の参考資料

- 4.3.1 Javadoc

5 クラスタ内のTopLinkアプリケーションのスケーリング

- 5.1 クラスタ内のTopLinkアプリケーションのスケーリングの理解

- 5.2 主なタスク

- 5.2.1 タスク1: キャッシュの整合性の構成

- 5.2.1.1 共有キャッシュの無効化

- 5.2.1.2 キャッシュのリフレッシュ

- 5.2.1.3 キャッシュ有効期限の設定

- 5.2.1.4 オプティミスティック・ロックの設定

- 5.2.1.5 キャッシュ・コーディネーションの使用

- 5.2.2 タスク2: TopLinkの有効化の確認

- 5.2.3 タスク3: すべてのアプリケーション・サーバーがクラスタ内にあることの確認

- 5.3 その他の参考資料

- 5.3.1 コード・サンプル

- 5.3.2 関連JavaDoc

6 サービスとしてのソフトウェアの提供

- 6.1 SaaSとしてのOracle TopLinkの理解

- 6.2 JPAエンティティの拡張可能化

- 6.2.1 主なタスク

- 6.2.1.1 タスク1: エンティティの構成

- 6.2.1.2 タスク2: スキーマの設計

- 6.2.1.3 タスク3: 追加マッピングの提供

- 6.2.1.4 タスク4: 永続性プロパティおよびデータ・リポジトリの構成

- 6.2.2 コード例

- 6.3 JAXB Beanの拡張可能化

- 6.3.1 主な手順

- 6.3.1.1 タスク1: Beanの構成

- 6.3.1.2 タスク2: 追加マッピングの提供

- 6.3.2 コード例

- 6.3.2.1 基本設定

- 6.3.2.2 テナントの定義

- 6.4 単一表マルチテナントの使用

- 6.4.1 主なタスク

- 6.4.1.1 タスク1: 単一表マルチテナントの有効化

- 6.4.1.2 タスク2: テナント識別子列の指定

- 6.4.1.3 タスク3: 実行時の識別子列の使用

- 6.4.2 その他の参考資料

- 6.4.2.1 コード・サンプル

- 6.4.2.2 関連Javadoc

- 6.5 外部メタデータ・ソースの使用

- 6.5.1 eclipselink-orm.xmlファイルの外部使用

- 6.5.2 主なタスク

- 6.5.2.1 タスク1: 永続性ユニットの構成

- 6.5.2.2 タスク2: サーバーの構成

- 6.5.3 その他の参考資料

- 6.5.3.1 Javadoc

7 XMLへのJPAのマッピング

- 7.1 JPAからXMLへのマッピングの概念の理解

- 7.1.1 XMLバインディングの理解

- 7.1.2 JAXBの理解

- 7.1.3 MOXyの理解

- 7.1.4 XMLデータ表現の理解

- 7.2 XMLへのJPAエンティティのバインディング

- 7.2.1 XMLへのJPAリレーションシップのバインディング

- 7.2.1.1 タスク1: アクセス・タイプおよびインポート・パッケージの定義

- 7.2.1.2 タスク2: 私有のリレーションシップのマッピング

- 7.2.1.3 タスク3: 共有参照リレーションシップのマッピング

- 7.2.1.4 JPAエンティティ

- 7.2.2 XMLへの複合主キーのバインディング

- 7.2.2.1 タスク1: XMLアクセッサ・タイプの定義

- 7.2.2.2 タスク2: ターゲット・オブジェクトの作成

- 7.2.2.3 タスク3: ソース・オブジェクトの作成

- 7.2.3 XMLへの埋込みIDクラスのバインディング

- 7.2.3.1 タスク1: XMLアクセッサ・タイプの定義

- 7.2.3.2 タスク2: ターゲット・オブジェクトの作成

- 7.2.3.3 タスク3: EmployeeCustomizerクラスとしてのDescriptorOrganizerの実装

- 7.2.3.4 タスク4: ソース・オブジェクトの作成

- 7.2.3.5 タスク5: PhoneNumberCustomizerクラスとしてのDescriptorCustomizerの実装

- 7.2.4 EclipseLinkのXMLバインディング文書の使用

- 7.3 XMLテキスト・ノードへの単純なJava値のマッピング

- 7.3.1 属性に対する値のマッピング

- 7.3.1.1 Javaオブジェクトからのマッピング

- 7.3.1.2 OXMメタデータ形式でのマッピングの定義

- 7.3.2 テキスト・ノードへの値のマッピング

- 7.3.2.1 単純なテキスト・ノードに対する値のマッピング

- 7.3.2.2 単純な順序でのテキスト・ノードへの値のマッピング

- 7.3.2.3 サブ要素のテキスト・ノードに対する値のマッピング

- 7.3.2.4 位置によるテキスト・ノードへの値のマッピング

- 7.4 XMLメタデータ表現を使用したJAXB注釈のオーバーライド

- 7.4.1 タスク1: XMLでの高度なマッピングの定義

- 7.4.2 タスク2: JAXBContextの使用方法の構成

- 7.4.3 タスク3: JAXB実装としてのMOXyの指定

- 7.5 マッピングに対するXPath述語の使用

- 7.5.1 XPath述語の理解

- 7.5.2 位置に基づくマッピング

- 7.5.3 属性値に基づくマッピング

- 7.5.3.1 タスク1: Customerエンティティの作成

- 7.5.3.2 タスク2: Addressエンティティの作成

- 7.5.3.3 タスク3: PhoneNumberエンティティの作成

- 7.5.4 セルフ・マッピング

- 7.6 動的JAXB/MOXyの使用

- 7.6.1 タスク1: XMLスキーマからの動的JAXBContextのブートストラップ

- 7.6.1.1 XMLスキーマからのブートストラップ

- 7.6.1.2 XMLスキーマ

- 7.6.1.3 スキーマのインポート/インクルードの処理

- 7.6.1.4 EntityResolverを実装して渡す方法

- 7.6.1.5 エラー処理

- 7.6.1.6 ClassLoaderの指定

- 7.6.2 タスク2: 動的エンティティの作成とXMLへのマーシャル

- 7.6.2.1 動的エンティティの作成

- 7.6.2.2 XMLへの動的エンティティのマーシャリング

- 7.6.3 タスク3: XMLからの動的エンティティのアンマーシャル

- 7.6.3.1 XMLからの動的エンティティのアンマーシャル

- 7.6.3.2 動的エンティティからのデータの取得

- 7.6.3.3 DynamicTypeを使用した、動的エンティティのイントロスペクション

8 コンテナ外部のTopLink JPAのテスト

- 8.1 JPAデプロイメントの理解

- 8.1.1 EntityManagerの使用

- 8.2 persistence.xmlファイルの構成

- 8.2.1 主なタスク

- 8.2.1.1 タスク1: persistence.xmlファイルの使用

- 8.2.1.2 タスク2: EntityManagerFactoryのインスタンス化

- 8.3 プロパティ・マップの使用

- 8.3.1 主なタスク

- 8.3.1.1 タスク1: persistence.xmlファイルの構成

- 8.3.1.2 タスク2: ブートストラップAPIの構成

- 8.3.1.3 タスク3: EntityManagerFactoryのインスタンス化

- 8.4 その他の参考資料

- 8.4.1 Javadoc

9 パフォーマンスの向上

- 9.1 パフォーマンス機能

- 9.1.1 オブジェクト・キャッシング

- 9.1.1.1 キャッシング注釈

- 9.1.1.2 @Cache注釈の使用

- 9.1.2 問合せ

- 9.1.2.1 読取り専用問合せ

- 9.1.2.2 結合フェッチ

- 9.1.2.3 バッチ読取り

- 9.1.2.4 フェッチ・サイズ

- 9.1.2.5 ページ区切り

- 9.1.2.6 キャッシュの使用方法

- 9.1.3 マッピング

- 9.1.3.1インダイレクション(遅延ロード)

- 9.1.3.2 読取り専用オブジェクト

- 9.1.3.3 ウィービング

- 9.1.4 トランザクション

- 9.1.5 データベース

- 9.1.5.1 接続プーリング

- 9.1.5.2 パラメータ化されたSQLとSQL文のキャッシュ

- 9.1.5.3 バッチ書込み

- 9.1.6 ツール

- 9.2 TopLinkが有効なアプリケーションの監視および最適化

- 9.2.1 パフォーマンス最適化の推奨事項およびヒント

- 9.2.2 タスク1: TopLinkプロファイラによるTopLinkパフォーマンスの測定

- 9.2.2.1 TopLinkプロファイラの有効化

- 9.2.2.2 プロファイラの結果へのアクセスおよび解釈

- 9.2.3 タスク2: アプリケーションのパフォーマンス問題の原因特定

- 9.2.4 タスク3: パフォーマンスが悪いアプリケーション・コンポーネントの変更

- 9.2.4.1 一般的なパフォーマンスの最適化の識別

- 9.2.4.2 スキーマ

- 9.2.4.3 マッピングおよびディスクリプタ

- 9.2.4.4 セッション

- 9.2.4.5 キャッシュ

- 9.2.4.6 データ・アクセス

- 9.2.4.7 問合せ

- 9.2.4.8 作業ユニット

- 9.2.4.9 アプリケーション・サーバーとデータベースの最適化

- 9.2.5 タスク4: パフォーマンスの再測定

10 HibernateからTopLinkへの移行

- 10.1 Hibernateの理解

- 10.2 主なタスク

- 10.2.1 タスク1: Hibernateのエンティティ注釈の変換

- 10.2.1.1 Select Before Update、Dynamic InsertおよびUpdate属性の変換

- 10.2.1.2 Optimistic Lock属性の変換

- 10.2.2 タスク2: Hibernateのカスタム・シーケンス・ジェネレータ注釈の変換

- 10.2.3 タスク3: Hibernateのマッピング注釈の変換

- 10.2.3.1 @ForeignKey注釈の変換

- 10.2.3.2 @Cache注釈の変換

- 10.2.4 タスク4: persistence.xmlファイルの変更

- 10.2.4.1 変更されたpersistence.xml

- 10.2.4.2 データベースの削除および作成

- 10.2.5 タスク5: Hibernate APIからEclipseLink APIへの変換

- 10.3 その他の参考資料

A Oracle TopLinkのインストール

- A.1 システム要件および動作要件

- A.1.1 その他の要件

- A.2 Oracle TopLinkのスタンドアロン・インスタンスのインストール

- A.3 Oracle WebLogic ServerでのOracle TopLinkおよびEclipseLinkのインストール

- A.4 Oracle Containers for Java EEでのOracle TopLinkのインストール

- A.5 Oracle Containers for Java EEでのEclipseLinkのインストール

Oracle® Fusion Middleware

Oracle TopLinkソリューション・ガイド

11g リリース1(11.1.1)

B66616-01(原本部品番号:E25034-02)

2011年11月

このマニュアルでは、TopLinkの機能およびTopLinkの一般的な開発プロセスを示す、多くのシナリオ(ユースケース)を説明します。

Oracle Fusion Middleware Oracle TopLinkソリューション・ガイド, 11g リリース1 (11.1.1)

B66616-01

Copyright © 2002, 2011, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントが、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供される場合は、次のNoticeが適用されます。

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007).Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.

このソフトウェアまたはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアまたはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、このソフトウェアまたはハードウェアを安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle およびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXはThe Open Groupの登録商標です。

このソフトウェアまたはハードウェアおよびドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

はじめに

Oracle TopLinkでは、リレーショナルおよびXMLの永続化のすべてのニーズに応える、高いパフォーマンス、スケーラビリティ、開発者の生産性、アーキテクチャと設計の柔軟性に優れ、実績のある標準に基づいたエンタープライズJavaソリューションが提供されています。

対象読者

様々なエンジニアがOracle TopLinkを使用しています。Oracle TopLinkのユーザーは、Oracle TopLinkに関連するテクノロジおよびサービス(たとえばJPA)の使用に習熟している必要があります。このドキュメントでは、関連する一般的なタスクの詳細は説明せず、Oracle TopLinkの機能を中心に説明します。

アプリケーション開発者は永続性サービスの次のテクノロジのいずれかを使用してアプリケーションを開発する必要があります。

- Java Persistence Architecture (JPA) 2.xとTopLink JPA拡張機能

- Java Architecture for XML Binding 2.x (JAXB)とTopLink Object-XML拡張機能

- TopLinkデータベースWebサービス(DBWS)

開発者は、Java SEおよびJava EEの概念およびプログラミング技法を十分に理解している必要があります。

TopLink JPAを使用する開発者は、http://jcp.org/en/jsr/detail?id=317のJava Persistence Architecture 2.0仕様に定義されているJPA 2.0の概念およびプログラミング技法を十分に理解している必要があります。

TopLink Object-XMLを使用する開発者は、http://jcp.org/aboutJava/communityprocess/pfd/jsr222/index.htmlのJava Architecture for XML Binding 2.0仕様に定義されているJAXB 2.0の概念およびプログラミング技法を十分に理解している必要があります。

TopLink DBWSを使用する開発者は、http://jcp.org/aboutJava/communityprocess/pfd/jsr222/index.htmlのJava API for XML-Based Web Services 2.0仕様に定義されているJAX-WS 2.0の概念およびプログラミング技法を十分に理解している必要があります。

管理者/デプロイヤはTopLinkの永続性テクノロジを使用して、アプリケーションをデプロイおよび管理する必要があります。これらのユーザーは、選択したアプリケーション・サーバーの基本的な操作を十分に理解している必要があります。

ドキュメントのアクセシビリティについて

オラクル社のアクセシビリティへ取組みの詳細は、Oracle Accessibility ProgramのWebサイトhttp://www.oracle.com/pls/topic/lookup?ctx&equals;acc&id=docaccを参照してください。

Oracleサポートへのアクセス

Oracleカスタマは、My Oracle Supportから電子サポートにアクセスできます。詳細は、http://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoまたはhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs (聴覚障害者向け)を参照してください。

関連ドキュメント

詳細は、次のドキュメントを参照してください。

- Oracle Fusion Middleware Oracle TopLinkコンセプト

- Oracle Fusion Middleware Java API Reference for EclipseLink

- http://wiki.eclipse.org/EclipseLink/UserGuideのEclipseLink Documentation Center

- Oracle Fusion Middlewareリリース・ノートfor Linux x86のOracle TopLink

表記規則

このマニュアルでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

イタリック体

イタリックは、ユーザーが特定の値を指定するプレースホルダ変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 概要

Oracle TopLinkには、Javaオブジェクトをリレーショナル・データベースに格納したり、JavaオブジェクトをXML文書に変換するための、強力で柔軟性の高いJava永続性フレームワークが備わっています。TopLinkには、Java EEアプリケーションの永続性レイヤーを実装するためのAPIとランタイム環境が備わっています。

TopLinkは、Eclipse Foundationのオープン・ソースの永続性フレームワークであるEclipseLinkに基づいて(包含して)います。EclipseLinkプロジェクトの詳細は、http://wiki.eclipse.org/EclipseLinkの『Eclipse Persistence Services Project (EclipseLink) wiki home』を参照してください。EclipseLink Documentation Centerは、http://wiki.eclipse.org/EclipseLink/Documentation_Centerを参照してください。

1.1 この本について

この『Oracle TopLinkソリューション・ガイド』では、TopLinkの機能および一般的な開発プロセスを示す、多数のシナリオまたはユース・ケースを説明します。これらは、プロジェクトを完了するために必要なすべてのタスクを順を追って説明するチュートリアルではありません。このドキュメントでは、特定の問題を解決するための概略プロセスおよび重要な部分のみの詳細を説明し、さらに詳細を説明する他のドキュメントへのリンクを示しています。

1.2 基礎的な必知事項

このドキュメントを利用するには、次のことをすでによく理解している必要があります。

- Java SEおよびJava EEの概念およびプログラミング技法。TopLinkの現在のリリースでは、Java EE 6がサポートされています。ただし、WebLogic Serverの現在のリリース(いくつかのユース・ケースで説明されています)では、Java EE 5のみがサポートされています。詳細は、次を参照してください。
Java

- Javaのホーム・ページ: http://www.oracle.com/us/technologies/java/index.html

- Java EE 5のチュートリアル: http://download.oracle.com/javaee/5/tutorial/doc/bnbpy.html

- Java EE 6のチュートリアル: http://download.oracle.com/javaee/6/tutorial/doc/bnbpy.html

- Javaに関する多数の書籍およびWebサイト

Oracle Java EEアプリケーション・サーバー

- Oracle WebLogic Serverのホーム・ページ: http://www.oracle.com/technetwork/middleware/weblogic/overview/index.html

- Oracle Glassfish Serverのホーム・ページ: http://www.oracle.com/technetwork/middleware/glassfish/overview/index.html

Oracle Java EE統合開発環境

- Oracle JDeveloper: http://www.oracle.com/technetwork/developer-tools/jdev/overview/index.html

- Oracle Enterprise Pack for Eclipse (OEPE): http://www.oracle.com/technetwork/developer-tools/eclipse/overview/index.html

- TopLinkは、Eclipse Foundationが提供するEclipseLinkに基づいています。次を参照してください。

- EclipseLinkプロジェクト・ホーム: http://wiki.eclipse.org/EclipseLink

- EclipseLink Documentation Center: http://wiki.eclipse.org/EclipseLink/Documentation_Center

- TopLink Java永続性アーキテクチャを使用して作業する場合は、http://jcp.org/en/jsr/detail?id=317のJava Persistence APIバージョン2.0に定義されているJPA 2.0の概念およびプログラミング技法をよく理解している必要があります。

- TopLink MOXyを使用して作業する場合は、http://jcp.org/en/jsr/detail?id=222のJava Architecture for XML Binding (JAXB) 2.0に定義されているJAXB 2.0の概念およびプログラミング技法をよく理解している必要があります。

- TopLink DBWSを使用する開発者は、http://jcp.org/en/jsr/detail?id=224のJava API for XML-Based Web Services (JAX-WS) 2.0に定義されているJAX-WS 2.0の概念およびプログラミング技法をよく理解している必要があります。

- JavaプラットフォームのRESTful (Representational State Transfer) Web Servicesのサポートはhttp://jcp.org/en/jsr/detail?id=311に説明されています。

1.3 ユース・ケース

この本では、次のユース・ケースが説明されています。

- 第2章「WebLogic ServerでのTopLinkの使用」: WebLogic ServerにデプロイされたTopLink Java Persistence Architecture (JPA) 2.0のアプリケーションに対してTopLinkを永続性プロバイダとして使用する方法。

- 第3章「GlassFish ServerでのTopLinkの使用」: GlassFish ServerにデプロイされたTopLink Java Persistence Architecture (JPA) 2.0のアプリケーションに対してTopLinkを永続性プロバイダとして使用する方法。

- 第4章「コンポジット永続性ユニットによる複数データベースの使用」: 複数の永続性ユニット(エンティティ・タイプの独自のセットがそれぞれに指定されている)を単一の永続性コンテキストとして公開する方法。

- 第5章「クラスタ内のTopLinkアプリケーションのスケーリング」: クラスタ化されたアプリケーション・サーバー環境でスケーラビリティを確保しながらTopLinkアプリケーションを構成する方法。

- 第6章「サービスとしてのソフトウェアの提供」: JPAエンティティまたはJAXB Beanを拡張可能にする方法。マルチ・テナントを使用する方法。外部メタデータ・ソースを使用する方法。

- 第7章「XMLへのJPAのマッピング」: TopLink MOXyを使用して、JPAエンティティをXMLにマップする方法。

- 第8章「コンテナ外部のTopLink JPAのテスト」: コンテナ外部のTopLinkアプリケーションをテストする方法。

- 第9章「パフォーマンスの拡張」: Oracle TopLinkで最高のパフォーマンスを得る方法。

- 第10章「HibernateからTopLinkへの移行」: Hibernate JPAの使用からTopLink JPAの使用へアプリケーションを移行する方法。

2 WebLogic ServerでのTopLinkの使用

この章では、WebLogic ServerにデプロイされたTopLink Java Persistence API (JPA) 2.0のアプリケーションに対してTopLinkを永続性プロバイダとして使用する方法を説明します。

この章には次の項が含まれます:

- 2.1項「TopLinkおよびWebLogic Serverの理解」

- 2.2項「開始時の必要事項」

- 2.3項「主なタスク」

2.1 TopLinkおよびWebLogic Serverの理解

WebLogic Serverは、エンタープライズ対応のスケーラブルなJava Platform, Enterprise Edition (Java EE)アプリケーション・サーバーです。WebLogic ServerにはJava EE 5.0の仕様が完全に実装されており、データベースやメッセージング・サービス、外部のエンタープライズ・システムへの接続など広範なサービスにアクセス可能な分散Javaアプリケーションを作成するための標準APIセットが用意されています。WebLogic Serverでは、Java EEの実装に加えて、堅牢かつセキュアで可用性が高くスケーラブルな環境にミッションクリティカルなアプリケーションを企業がデプロイできるようになっています。これらの特徴により、企業はWebLogic Serverインスタンスのクラスタを構成し、ロードを分散し、ハードウェアまたはその他の障害が発生した際にかわりとなる処理能力を提供できます。WebLogic Serverのこれらおよび他の機能の詳細は、WebLogic Serverの紹介を参照してください。

2.1.1 WebLogic ServerでTopLinkを使用する利点

WebLogic Serverでは他の永続性プロバイダを使用でき、TopLinkは他のアプリケーション・サーバーで使用できるので、WebLogic ServerをTopLinkとともに使用すると、次のような多くの利点があります。

- TopLinkはWebLogic Serverのすべてのディストリビューションに含まれているので、TopLinkをWebLogic Serverドメインのデフォルト永続性プロバイダにして、JPA 2.0をサポートするWebLogic Serverを構成できます。2.3.1項「タスク1: デフォルトJPAプロバイダとしてTopLinkを設定(WebLogic Server 11g)」および2.3.2項「タスク2: WebLogic Server 11gでJPA 2.0をサポートするためのパッチの適用」を参照してください。

- Oracle WebLogic Suiteには、データ・キャッシング、データ・レプリケーションおよび分散コンピューティング・サービスを提供するJavaベースのインメモリー・データグリッド製品であるOracle Coherenceが含まれています。WebLogic ServerとCoherenceは密に統合されているので、アプリケーションはCoherenceのデータ・キャッシュを使用できます。WebLogic ServerのアプリケーションはTopLink Gridを使用できます。TopLink GridはTopLinkとCoherenceの間を統合したもので、TopLinkがCoherenceをエンティティのレベル(L2)キャッシュおよび永続性レイヤーとして使用できるようにします。これらの統合の使用方法は、このドキュメントでは説明しません。詳細は、Oracle Coherence開発者ガイドおよび『Oracle Fusion Middleware Oracle TopLinkのためのCoherence Grid統合ガイド』を参照してください。

注意:

別途ライセンスされた製品としてCoherenceを入手して、WebLogic Server Standard EditionおよびWebLogic Server Enterprise Editionを使用することもできます。詳細は、前述のリンクを参照してください。

- WebLogic ServerのTopLinkロギング統合では、包括的な統合ロギング・インフラストラクチャが実現されています。2.3.5項「タスク5: ロギング統合の使用または再構成」を参照してください。

- WebLogic Serverは、StrutsとJavaServer Faces (JSF)に基づいたエンド・ツー・エンドのJava EEフレームワークであるOracle Application Framework (ADF)をサポートしています。ADFでは、インフラストラクチャ・サービスおよび視覚的で宣言的な開発エクスペリエンスを実現することにより、アプリケーション開発が簡素化されています。TopLinkおよびADFをともに使用することにより、完全なJava EEアプリケーション・インフラストラクチャが実現されます。ADFの使用方法は、このドキュメントでは説明しません。『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』を参照してください。

- WebLogic Server、TopLinkおよびADFはすべてJDeveloperと統合されています。JDeveloperは、TopLinkを永続性プロバイダとして使用し、WebLogic Serverにデプロイされるアプリケーションを含むJava EEアプリケーションのモデリング、開発、デバッグ、最適化およびデプロイをエンドツーエンドでサポートするOracleの統合開発環境(IDE)です。JDeveloperの使用方法は、このドキュメントでは説明しません。JDeveloperに関する一般的な情報は、http://www.oracle.com/technetwork/developer-tools/jdev/overview/index.htmlを参照してください。JDeveloperのタスクに関する情報は、JDeveloper IDEのJDeveloperオンライン・ヘルプを参照してください。

2.1.2 他のFusion Middleware製品に対するTopLinkの関係

図2-1は、他のOracle製品に対するWebLogic ServerとTopLinkの関係および使用方法を示しています。JDeveloper (またはOracle Enterprise Pack for EclipseまたはNetBeans)はJava EEアプリケーションの開発に使用できます。TopLinkは永続性プロバイダとして使用します。データ・キャッシング、データ・レプリケーションおよび分散コンピューティング・サービスには、Oracle Coherenceを(TopLink Gridの統合を介して)使用します。WebLogicはアプリケーション・サーバーとして使用し、TopLink JPAアプリケーションからデータの永続化に関してはOracleデータベースを使用し、TopLink MOXyアプリケーションからのデータの永続化に関してはXMLを使用します。

図2-1 WebLogic Server、TopLinkおよび関連製品の関係

図2-1「WebLogic Server、TopLinkおよび関連製品の関係」の説明

2.2 開始時の必要事項

Oracle WebLogic Serverに対して、TopLink アプリケーションを開発およびデプロイするには、次のものが必要です。

- WebLogic Server。このドキュメントは、Oracle WebLogic Serverリリース 11gR1 (10.3.6)に基づいています。
詳細およびダウンロードは、Oracle Technology Networkのhttp://www.oracle.com/technetwork/middleware/weblogic/overview/index.htmlを参照してください。

- Oracle、Oracle Express、MySQLなどのJDBC準拠データベース。
Oracleデータベースについては、http://www.oracle.com/technetwork/database/enterprise-edition/overview/index.htmlを参照してください。Oracle Express Editionについては、http://www.oracle.com/technetwork/database/express-edition/overview/index.htmlを参照してください。MySQLについては、http://www.oracle.com/us/products/mysql/index.htmlを参照してください。

- 必須ではありませんが、Java開発環境(IDE)を開発に使用すると便利です。たとえば、JDeveloper、Oracle Enterprise Pack for Eclipse (OEPE)およびOracle NetBeansにはすべて、高度なJava EE開発ツールが用意されています。このドキュメントでは、WebLogic Serverのスタンドアロン・インスタンスについて説明しますが、JDeveloperとOEPEの両方にWebLogic Serverの埋込みバージョンが含まれています。
JDeveloperについては、http://www.oracle.com/technetwork/developer-tools/jdev/downloads/index.htmlを参照してください。OEPEについては、http://www.oracle.com/technetwork/developer-tools/eclipse/overview/index.htmlを参照してください。NetBeansについては、http://www.oracle.com/us/products/tools/050845.htmlを参照してください。

2.3 主なタスク

TopLink JPAアプリケーションをWebLogic Serverで実行するには、次の手順に示すように、WebLogic Serverを構成してサーバーとアプリケーションの特定の設定を調整する必要があります。

- タスク1: デフォルトJPAプロバイダとしてTopLinkを設定(WebLogic Server 11g)

- タスク2: WebLogic Server 11gでJPA 2.0をサポートするためのパッチの適用

- タスク3: WebLogic ServerのEclipseLinkのバージョンの更新

- タスク4: WebLogic ServerのJMX MBean拡張の構成

- タスク5: ロギング統合の使用または再構成

- タスク6: TopLinkを使用したJavaアプリケーションへの永続性の追加

- タスク7: データ・ソースの構成

- タスク8: Oracleデータベースの高度な機能を使用するためのドメインの拡張

- タスク10: WebLogic Serverの起動とアプリケーションのデプロイ

- タスク11: アプリケーションの実行

- タスク12: WebLogic Serverの永続性設定の構成および監視

2.3.1 タスク1: デフォルトJPAプロバイダとしてTopLinkを設定(WebLogic Server 11g)

JPAアプリケーションのpersistence.xmlファイルに、エンティティごとにどのJPA永続性プロバイダを使用するかを指定できます。ただし、永続性プロバイダが指定されていない場合は、WebLogic Serverに指定されているドメイン全体のデフォルト・プロバイダが使用されます。

注意:

Oracle TopLinkは、WebLogic Server 12cのデフォルトのJPA永続性プロバイダなので、そのリリース以降でデフォルト・プロバイダとして使用する場合は何もする必要はありません。

Oracle TopLinkは、WebLogic Server 11g (10.3.n)のデフォルトのJPA永続性プロバイダとしては設定されていないので、これらのリリースではデフォルト・プロバイダになるように設定する必要があります。

注意:

TopLinkがデフォルトの永続性プロバイダでない理由は、WebLogic Server 10.3の以前のバージョンとの下位互換性を維持するためです。これにより、永続性プロバイダを変更せずに、WebLogic Serverのバージョンを今後の10.3のパッチ・セットにアップグレードできようになっています。

デフォルト・プロバイダを変更しても、すでにデプロイされているアプリケーションには影響しません。設定は、サーバーを再起動またはアプリケーションを手動で再デプロイしたときに有効になります。

TopLinkをデフォルトのJPAプロバイダとしてWebLogic Server管理コンソールで指定するには:

1. WebLogic Serverを開始して、管理コンソールを開始します。

2. まだ行っていない場合は、管理コンソールのチェンジ・センターで「ロックして編集」をクリックします。

3. 管理コンソールの左ペインのドメイン構造の下で、ドメイン名を選択します。

4. 「構成」→「一般」→「JPA」を選択します。

5. 「デフォルトJPAプロバイダ」リストで、「TopLink」を選択します。

6. 「保存」をクリックします。

7. これらの変更を有効にするために、管理コンソールの「チェンジ・センター」で「変更のアクティブ化」をクリックします。

2.3.2 タスク2: WebLogic Server 11gでJPA 2.0をサポートするためのパッチの適用

WebLogic Server 11gR1 (10.3.6)はデフォルトでJPA 1.0をサポートしています。ただし、パッチを適用すれば、JPA 2.0をサポートできます。手順の詳細は、『Oracle Fusion Middleware Oracle WebLogic Server Enterprise JavaBeansバージョン3.0のプログラミング』のWebLogic ServerのTopLinkでJPA 2.0を使用する方法に関する項を参照してください。

注意:

JPA 2.0には下位互換性があるので、JPA 1.0 APIを使用するアプリケーションをサポートできます。

注意:

WebLogic Server 12cはデフォルトでJPA 2.0をサポートしています。

2.3.3 タスク3: WebLogic ServerのEclipseLinkのバージョンの更新

TopLinkにはEclipseLinkのすべてのライブラリが含まれています。これらのライブラリでは、JPA、MOXy、DBWSおよび他の永続性サービスおよび変換サービスがサポートされています。TopLinkのEclipseLinkのバージョンは、Eclipse Foundationから入手できる最新のバージョンではない可能性があります。ただし、WebLogic ServerのFilteringClassLoaderおよび共有ライブラリ機能を使用すれば、EclipseLinkのバージョンをアップグレードできます。

様々なリリースでサポートされている内容については、次を参照してください。

- http://www.oracle.com/technetwork/middleware/ias/jpa-082702.html#eclipselinkにあるOracle TopLink: JPA認証に関する項

- http://www.oracle.com/technetwork/middleware/ias/weblogic-086699.htmlにあるOracle TopLinkおよびWebLogicのサポートに関する項

FilteringClassLoaderは、デプロイメント・ディスクリプタを構成して、特定のパッケージが常にシステム・クラス・ローダーではなくアプリケーションからロードされるように指定するためのメカニズムとして用意されています。このメカニズムを使用すれば、新しいバージョンのEclipseLinkがアプリケーションで使用されるように指定できます。クラスローダーのフィルタリングの詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverアプリケーションの開発』のフィルタリング・クラスローダーの使用方法に関する項を参照してください。

共有ライブラリは、複数のエンタープライズ・アプリケーションで共有できるJava EEモジュールです。共有ライブラリはWebLogic Serverのターゲットにデプロイされ、その後アプリケーションで参照できるようになります。デプロイされると、WebLogic Serverでは、共有ライブラリの内容がアプリケーションとマージされます。さらに、共有ライブラリは標準のJava EEアーカイブとしてパッケージ化できるので、デプロイ時には、ディスクリプタもアプリケーションとマージされます。WebLogic Serverの共有ライブラリ詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverアプリケーションの開発』のJava EEの共有ライブラリおよびオプション・パッケージの作成に関する項を参照してください。

WebLogic Serverにデプロイされたアプリケーションで使用されるEclipseLinkのバージョンを更新するには、次を実行します:

1. 必要なEclipseLinkのバージョンのeclipselink-version_no.zipをhttp://www.eclipse.org/eclipselink/downloads/index.phpのEclipseLink Webサイトからダウンロードします。

2. 次のアイテムを含む共有ライブラリを、eclipselink-shared-lib.earなどの名前を付けた標準Java EE Enterprise Archive (EAR)として準備します。

META-INF/weblogic-application.xml
META-INF/application.xml
lib/eclipselink.jar

EARの作成の詳細は、『Oracle Fusion Middleware Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』のWebアプリケーションの作成と構成に関する項を参照してください。

3. 次に示すように、サブ要素<package-name>org.eclipse.persistence.*</package-name>が指定されたprefer-application-packages要素をアプリケーションのweblogic-application.xmlディスクリプタ・ファイルに追加します。

<weblogic-application>
<prefer-application-packages>
<package-name>org.eclipse.persistence.*</package-name>
</prefer-application-packages>
</weblogic-application>

4. アプリケーションのapplication.xmlファイルを作成します。このファイルは、ランタイム・ライブラリのマージをサポートするために必要です。最小構成は次のとおりです。

<application>
<display-name>eclipselink-shared-lib</display-name>
<module>
<java></java>
</module>
</application>

5. 拡張の名前、仕様バージョンおよび実装バージョンをEARのMETA-INF/MANIFEST.MFファイルに追加します。たとえば、antを使用している場合は、次を実行します:

<target name="package" depends="prepare">
<jar destfile="dist/${ant.project.name}.ear">
<metainf dir="etc" includes="*.xml"/>
<manifest>
<attribute name="Extension-Name" value="eclipselink"/>
<attribute name="Specification-Version" value="2.0"/>
<attribute name="Implementation-Version" value="2.2.0"/>
</manifest>
<fileset dir="build" includes="**/*"/>
</jar>
</target>

デプロイ時には、デプロイされた共有ライブラリのメタデータとして、WebLogic Serverがこの属性を使用します。

最終的なEARファイル、次のようになります。

META-INF/
META-INF/MANIFEST.MF
META-INF/application.xml
META-INF/weblogic-application.xml
lib/
lib/eclipselink.jar

6. eclipselink-shared-lib.earをWebLogic Serverにデプロイします。この結果、サーバーeclipselink#2.0@2.2.0で新しいライブラリが使用可能になります。

7. 次に示すように、更新されたバージョンのEclipseLinkを使用するアプリケーションのweblogic-application.xmlファイルに、共有ライブラリへの参照を追加します。

<weblogic-application>
<library-ref>
<library-name>eclipselink</library-name>
<specification-version>2.0</specification-version>
<implementation-version>2.2.0</implementation-version>
</library-ref>
</weblogic-application>

2.3.4 タスク4: WebLogic ServerのJMX MBean拡張の構成

WebLogic ServerはJava Management Extensions (JMX) MBeanを使用して、WebLogic Serverのリソースを構成、監視および管理します。TopLinkのアプリケーションの場合、MBeanは永続性ユニットの様々な面の監視および設定に使用され、ロギングにも使用されます。

注意:

TopLinkのアプリケーションがWebLogic Serverにデプロイされると、デプロイ時ではなくデータベースへの接続時にMBeanがデプロイされます。

WebLogic ServerでのMBeanの使用方法の詳細は、『Oracle Fusion Middleware Oracle WebLogic Server JMXによるカスタム管理ユーティリティの開発』および『Oracle Fusion Middleware Oracle WebLogic Server JMXによる管理の容易なアプリケーションの開発』を参照してください。

WebLogic ServerでのTopLinkのロギングの詳細は、2.3.5項「タスク5: ロギング統合の使用または再構成」を参照してください。

デフォルトでは、EclipseLinkアプリケーションをOracle WebLogic Serverにデプロイすると、EclipseLinkのランタイムが、各EclipseLinkセッションのOracle WebLogic Server JMXサービスに対して、次のJava Management Extensions (JMX) MBeanをデプロイします。

- org.eclipse.persistence.services.DevelopmentServices: これは、EclipseLinkの内部的なEclipseLinkセッションをJMX経由で管理する機能を提供するためのクラスです。

- org.eclipse.persistence.services.RuntimeServices: これは、EclipseLinkの外部的なEclipseLinkセッションをJMX経由で管理する機能を提供するためのクラスです。

このJMX MBeanが公開するAPIを使用すれば、自分で記述したJMXコードを使用してTopLinkセッションの実行時にアクセスおよび構成をしたり、JConsoleなどのサード・パーティのJMX管理アプリケーションを使用してTopLinkアプリケーションを統合したりできます。

カスタムMBeanに関するアクセス情報を入手するには、まず匿名ルックアップを有効にしてから、別のツールを使用してMBean情報にアクセスします。

honeymoonerルックアップを管理コンソールで有効にするには、次を実行します:

1. まだ行っていない場合は、管理コンソールのチェンジ・センターで「ロックして編集」をクリックします。

2. まず左側のペインで、ドメインを選択し、ドメインの「設定」ページを開きます。

3. 「セキュリティ」→「一般」を展開します。

4. 「匿名Adminのルックアップを有効化」を選択します。

5. これらの変更を有効にするために、管理コンソールの「チェンジ・センター」で「変更のアクティブ化」をクリックします。

様々なツールを使用してMBeanにアクセする方法の詳細は、『Oracle Fusion Middleware Oracle WebLogic Server JMXによる管理の容易なアプリケーションの開発』のカスタムMBeanへのアクセスに関する項を参照してください。

WebLogic Server管理コンソールのカスタムMBeanのモニタリングの詳細は、Oracle Fusion Middleware Oracle WebLogic Server管理コンソールのオンライン・ヘルプのカスタムMBeanの監視に関する項を参照してください。

2.3.5 タスク5: ロギング統合の使用または再構成

デフォルトでは、TopLinkのロギングはWebLogic Serverのロギング・インフラストラクチャに統合されます。統合の動作の詳細およびそれをオーバーライドする方法は、次の項を参照してください。WebLogic Serverのロギングの詳細は、次を参照してください。

- Oracle Fusion Middleware Oracle WebLogic Serverアプリケーション・ロギングのためのロギング・サービスの使用

- Oracle Fusion Middleware Oracle WebLogic Serverログ・ファイルの構成とログ・メッセージのフィルタ処理

- Oracle Fusion Middleware Oracle WebLogic Server管理コンソール・オンライン・ヘルプのロギングに関する項

JPA永続性ユニットに対するロギングの構成方法の詳細は、http://wiki.eclipse.org/EclipseLink/Examples/JPA/LoggingにあるEclipseLinkドキュメントの『How to Configure Logging』を参照してください。

2.3.5.1 ロギング統合の動作方法

デフォルトでは、WebLogic Serverのロギング実装は永続性コンテキストに注入されるので、WebLogic Serverのロギング構成に従ってTopLinkのすべてのロギング・メッセージが出力されるようになります。

この統合の結果、表2-1に示すように、TopLinkのロギング・レベルがWebLogic Serverのロギング・レベルに変換されます。

表2-1 WebLogic Serverのロギング・レベルへのTopLinkのロギング・レベルのマッピング

TopLinkのロギング・レベル

WebLogic Serverのロギング・レベル

ALL、FINEST、FINER、FINE

DEBUG

CONFIG

INFO

INFO

NOTICE

WARNING

WARNING

SEVERE

ALERT

OFF

OFF

表2-2に示すように、WebLogic Serverのロギング・レベルがTopLinkのレベルにマップされます。

表2-2 TopLinkのロギング・レベルへのWebLogic Serverのロギング・レベルのマッピング

WebLogic Serverのロギング・レベル

TopLinkのロギング・レベル

TRACE、DEBUG

FINEST

INFO

CONFIG

NOTICE

INFO

WARNING

WARNING

ERROR、CRITICAL、ALERT

SEVERE

EMERGENCY、OFF

OFF

2.3.5.2 管理コンソールでの永続性ユニットのロギング・レベルの表示

2.3.11項「タスク12: WebLogic Serverの永続性設定の構成および監視」に説明されているように、永続性ユニットに定義されているTopLinkのロギング・レベルを管理コンソールに表示できます。ただし、デフォルトのWebLogic Server/TopLinkロギング統合を使用すると、persistence.xmlに設定されているこのロギング・レベルがオーバーライドされることに注意してください。統合をオーバーライドする手順は、次の2.3.5.3項「デフォルト・ロギング統合のオーバーライド」を参照してください。

デフォルト統合を使用すると、永続性に対するEJBロギング・オプションがすべてマップされて、管理コンソールのTopLinkのロギング出力が制御されます。

2.3.5.3 デフォルト・ロギング統合のオーバーライド

TopLinkのロギング・レベルはpersistence.xmlファイルに設定します。ただし、WebLogic Severとのデフォルト・ロギング統合を受け入れると、これらの設定は無視され、WebLogic Serverに設定されているロギング構成が使用されます。TopLinkのロギング・レベルは、TopLinkのネイティブのロギング実装を使用する場合のみに使用されます。

次のようにeclipselink.logging.loggerプロパティ名を別の設定にすると、デフォルト・ロギング統合をオーバーライドできます。

TopLinkのデフォルト・ロギングを有効にするには、eclipselink.logging.loggerプロパティを次のように設定します。

<property name="eclipselink.logging.logger" value="DefaultLogger"/>

java.util.loggingを使用して、java.util.loggingなどの別のロギング実装をTopLinkメッセージに対して使用することもできます。

<property name="eclipselink.logging.logger" value="JavaLogger"/>

2.3.5.4 TopLinkのロギングを公開するためのWebLogic Serverの構成

TopLinkのネイティブのロギング実装を使用する場合は、登録されたログの宛先にWebLogic ServerがJava Virtual Machine (JVM)の出力をリダイレクトするように構成すれば、TopLinkのロギング・メッセージをWebLogic Serverドメインのログ・ファイルに引き続き表示できます。

リダイレクトの構成の詳細および手順は、『Oracle Fusion Middleware Oracle WebLogic Serverログ・ファイルの構成とログ・メッセージのフィルタ処理』のJVM出力のリダイレクトに関する項を参照してください。管理コンソールでこのオプションを設定するには、Oracle Fusion Middleware Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJVM出力のリダイレクトに関する項を参照してください。

2.3.5.5 その他の考慮事項

次の考慮事項に注意してください。

- メッセージID 2005000は、TopLinkのすべてのログ・メッセージに対して使用されています。

- 実行時にアプリケーションのエンティティ・マネージャ・ファクトリがTopLinkのロギング・インフラストラクチャおよびTopLinkのロギング設定のみを使用する場合でも、(ロギング・レベルの設定によっては)WebLogic Serverの統合ロガーによって処理される一部のロギング・メッセージがWebLogic Serverのコンソールまたはサーバー・ログにデプロイ中に表示される場合があります。

- WebLogic ServerのインストールにバンドルされているEclipseLinkとは別のバージョンを(フィルタリング・クラスローダーを使用して)使用する場合に、デフォルトの統合ロギングを使用しようとすると、クラスローディングの競合のためにエラーが発生する可能性があります。この問題を回避するには、統合されたWebLogic Serverロガー以外のものにeclipselink.logging.loggerプロパティを明示的に設定してください。

2.3.6 タスク6: TopLinkを使用した、Javaアプリケーションへの永続性の追加

TopLink JPAを使用してアプリケーションに対する永続性を実現することは、この章で説明する他のすべてのタスクで仮定されている基本的なタスクですが、実際のJPAプログラミング技法の大部分はこのドキュメントでは説明しません。WebLogic Serverでは、この章で説明する詳細以外に、TopLinkアプリケーションに対する特別な要件はありません。

これは、TopLinkが、Eclipse Foundationのオープン・ソースの永続性プロジェクトであるEclipseLinkに基づいているためです。EclipseLink 2.nは、Java Persistence APIバージョン2.0仕様のリファレンス実装です。TopLinkには、EclipseLinkのすべてのJARおよびOracleの追加のツールおよび機能が含まれています。そのため、TopLinkを使用して永続性レイヤーをJavaアプリケーションに追加する際には、JPAおよびEclipseLinkで提供されるすべての範囲の機能を利用できます。

この章では、TopLink (ランタイムおよびAPI)をWebLogic Serverで使用する場合に固有の機能、設定およびタスクについて説明します。JPAを使用したJavaアプリケーションの開発、パッケージ化およびデプロイの詳細は、次を参照してください。

- http://wiki.eclipse.org/EclipseLinkにあるEclipseLinkプロパティのwiki

- http://wiki.eclipse.org/EclipseLink/Documentation_CenterにあるEclipseLink Documentation Center

- http://jcp.org/en/jsr/detail?id=317にあるJava Persistence APIバージョン2.0仕様

- http://download.oracle.com/javaee/5/tutorial/doc/bnbpy.htmlにあるJava EE 5チュートリアルの第V部「永続性」

- JPAを使用したJavaアプリケーションのプログラミングについて説明したサード・パーティの書籍

TopLinkの機能と概念の詳細は、第1章「概要」および『Oracle Fusion Middleware Oracle TopLinkコンセプト』を参照してください。

関連するWebLogic Serverのプログラミング・トピックについては、WebLogic Serverのドキュメント・セットのドキュメント(『Oracle Fusion Middleware Oracle WebLogic Serverインフォメーション・ロードマップ』を参照)、特に次のドキュメントを参照してください。

- 『Oracle Fusion Middleware Oracle WebLogic Server Enterprise JavaBeansバージョン3.0のプログラミング』

- 『Oracle Fusion Middleware Oracle WebLogic Serverアプリケーションの開発』

- 『Oracle Fusion Middleware Oracle WebLogic Serverへのアプリケーションのデプロイ』

- 『Oracle Fusion Middleware Oracle WebLogic Server JDBCのプログラミング』

2.3.7 タスク7: データ・ソースの構成

WebLogic Serverでデータベース接続を構成するには、JDBCデータ・ソースをWebLogic Serverドメインに追加します。各WebLogicデータ・ソースは、データベース接続のプールを保有しています。各アプリケーションは、JNDIツリーまたはローカル・アプリケーション・コンテキストでデータ・ソースをルックアップし、getConnection()メソッドを使用してデータベース接続を予約します。データ・ソースおよびその接続プールは、システムの効率的な稼働を維持するための接続管理プロセスを備えています。

WebLogic ServerでJDBCを使用する方法の詳細は、次を参照してください。

- WebLogic ServerでJDBCを使用する方法の詳細なドキュメントは、『Oracle Fusion Middleware Oracle WebLogic Server JDBCデータ・ソースの構成と管理』の次の項を特に参照してください。

- WebLogic JDBCリソースの構成

- JDBCデータ・ソースの構成

- WebLogic管理コンソールでJDBCデータ・ソースを操作する方法の詳細は、Oracle Fusion Middleware Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJDBCの構成に関する項にあるトピックを参照してください。

2.3.7.1 JPAアプリケーションのデータ・ソースを構成する方法

WebLogic ServerにデプロイされたJPAアプリケーションのデータ・ソースは、次のような様々な方法で構成できます。

- グローバル・スコープのJTAデータ・ソースの構成

- アプリケーション・スコープのJTAデータ・ソースの構成

- 非JTAデータ・ソースの構成およびアプリケーションのトランザクション管理

2.3.7.2 グローバル・スコープのJTAデータ・ソースの構成

最も一般的なデータ・ソース構成は、グローバル・スコープのJNDIデータ・ソースで、トランザクション管理にJTAを使用して、persistence.xmlファイルに指定します。構成は簡単で、複数のアプリケーションがデータ・ソースにアクセスできます。

次を実行します:

- WebLogic Serverでのデータ・ソースの作成

- persisence.xmlの構成

2.3.7.2.1 WebLogic Serverでのデータ・ソースの作成

グローバル・スコープのJNDIデータ・ソースをWebLogic Server管理コンソールで設定するには、次を実行します:

1. Oracle Fusion Middleware Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJDBC汎用データ・ソースの作成に関する項の説明に従って、新しいデータ・ソースを作成します。

注意:

TopLinkは、名前による標準のJNDIデータ・ソース・ルックアップを使用してアクセスできるWebLogic Serverのデータ・ソースと互換性があります。これらの手順では、汎用データ・ソースのウィザードについて説明します。

2. 必要に応じて、「新しいJDBCデータ・ソースの作成」ウィザードに値を入力します。詳細は、Oracle Fusion Middleware Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJDBCデータ・ソースの作成に関する項を参照してください。

重要:

JDBCデータ・ソースのプロパティ・ページの「JNDI名」に使用する値は、persistence.xmlの<jta-data-source>要素に使用する値と同じである必要があります。

3. 『Oracle Fusion Middleware Oracle WebLogic Server JDBCデータ・ソースの構成と管理』の接続プール機能の構成に関する項の説明に従って、接続プールを構成します。接続プールの構成は、アプリケーションからの同時リクエストをTopLinkが処理する能力に影響を及ぼす可能性があります。リソースおよびアプリケーションの応答性を最適化するために接続プールをチューニングするのと同じ方法で、プロパティをチューニングしてください。

2.3.7.2.2 persisence.xmlの構成

次の例2-1に示すように、persistence.xmlファイルに、transaction-typeがJTAであることを指定して、データ・ソースの名前をjta-data-source要素(前にjdbc/が付く場合とそうでない場合があります)に指定します。

例2-1 JTAを使用するJNDIデータ・ソースが指定されたpersistence.xmlファイル

...
<persistence-unit name="example" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>JDBC Data Source-1</jta-data-source>
<class>org.eclipse.persistence.example.jpa.server.business.Cell</class>
<class>org.eclipse.persistence.example.jpa.server.business.CellAttribute</class>
</persistence-unit>

2.3.7.3 アプリケーション・スコープのJTAデータ・ソースの構成

トランザクション管理にJTAを使用するアプリケーション・スコープのデータ・ソースを構成するには、次のタスクを実行します。

1. データ・ソースがアプリケーション・スコープであることの指定

2. WebLogicのアプリケーション構成へのJDBCモジュールの追加

3. JTAデータ・ソースを使用するためのJPA永続性ユニットの構成

2.3.7.3.1 データ・ソースがアプリケーション・スコープであることの指定

アプリケーション・スコープのデータ・ソースを定義するには、name-jdbc.xml JDBCモジュール・ファイルを作成して、アプリケーションのEARアーカイブのMETA-INFフォルダに置きます。例2-2に示すように、そのファイルのjdbc-data-source-paramsセクションに<scope>Application</scope>を追加します。

例2-2 name-jdbc.xmlファイルに定義されたJDBCデータ・ソース

<jdbc-data-source ...>
...
<jdbc-data-source-params>
<jndi-name>SimpleAppScopedDS</jndi-name>
<scope>Application</scope>
</jdbc-data-source-params>
</jdbc-data-source>

ヒント:

2.3.7.2項「グローバル・スコープのJTAデータ・ソースの作成」の説明に従って、WebLogic Server管理コンソールからグローバル・スコープのデータ・ソースを作成すれば、name-jdbc.xmlファイルのフレームワークを作成できますが、次の点が異なります。

- データ・ソースをサーバーに関連付けないでください

- <scope>要素を手動で追加してください

JDBCモジュール構成ファイルおよびjdbc-data-source (<jdbc-driver-paramsおよび<jdbc-connection-pool-paramsを含む)の詳細は、『Oracle Fusion Middleware Oracle WebLogic Server JDBCデータ・ソースの構成と管理』のWebLogic JDBCリソースの構成に関する項を参照してください。

2.3.7.3.2 WebLogicのアプリケーション構成へのJDBCモジュールの追加

例2-3に示すように、EARアーカイブの/META-INF/weblogic-application.xmlアプリケーション・デプロイメント・ディスクリプタにJDBCモジュールへの参照を追加します。これにより、アプリケーションで使用するデータ・ソースが登録されます。

例2-3 weblogic-application.xmlに定義されたJDBCモジュール

<wls:module>
<wls:name>SimpleAppScopedDS</wls:name>
<wls:type>JDBC</wls:type>
<wls:path>META-INF/simple-jdbc.xml</wls:path>
</wls:module>

weblogic-application.xmlアプリケーション・デプロイメント・ディスクリプタの詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverへのアプリケーションのデプロイ』のアプリケーション・デプロイメント・ディスクリプタの理解に関する項および『Oracle Fusion Middleware Oracle WebLogic Serverアプリケーションの開発』のエンタープライズ・アプリケーション・デプロイメント・ディスクリプタの要素に関する項を参照してください。

2.3.7.3.3 JTAデータ・ソースを使用するためのJPA永続性ユニットの構成

TopLinkランタイムがアプリケーション・スコープのデータ・ソースをレイジー・ルックアップできるようにするには、persistence.xmlの永続性ユニットの定義に追加のデータ・ソース・プロパティを指定する必要があります。例2-4に示すように、JTAデータ・ソースの場合は、javax.persistence.jtaDataSource完全修飾プロパティに値java:/app/jdbc/data_source_nameを指定して追加します。

<jta-data-source>プロパティの値と<javax.persistence.jtaDataSource>プロパティの値は一致する必要があります。

例2-4 persistence.xmlのJTAデータ・ソース定義

<?xml version="1.0" encoding="windows-1252" ?>
<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"
version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="employee" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/app/jdbc/SimpleAppScopedDS</jta-data-source>
<properties>
<property name="javax.persistence.jtaDataSource"
value="java:/app/jdbc/SimpleAppScopedDS" />
</properties>
</persistence-unit>
</persistence>

2.3.7.4 非JTAデータ・ソースの構成およびアプリケーションのトランザクション管理

アプリケーションが管理する非JTAデータ・ソースを構成するには、2.3.7.3項「アプリケーション・スコープのJTAデータ・ソースの構成」の説明と同じことをしますが、例2-5に示すように、非JTAデータ・ソースを指定して、非JTAデータ・ソースを使用するようにJPAの永続性を構成します。

例2-5 persistence.xmlの非JTAデータ・ソースの定義

<?xml version="1.0" encoding="windows-1252" ?>
<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"
version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="employee" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<non-jta-data-source>OracleDS</non-jta-data-source>
<properties>
<property name="javax.persistence.nonJtaDataSource"
value="OracleDS" />
</properties>
</persistence-unit>
</persistence>

たとえば、『Oracle Fusion Middleware Oracle WebLogic Server JTAのプログラミング』のEJBアプリケーションのトランザクションに関する項に説明されているように、トランザクションを処理するコードをアプリケーションに記述します。

2.3.7.5 設定の一致の確認

データ・ソース構成の特定の設定は、アプリケーションのejbModule/META-INF/persistence.xmlファイルの特定の設定と一致する必要があります。WebLogic Serverのデータ・ソース構成については、構成ファイルまたは管理コンソールで設定を確認できます。

管理コンソールでは、次のように設定を確認します。

1. 「ドメイン構造」ツリーで「サービス」を開き、「データ・ソース」を選択します。

2. 「JDBCデータ・ソースのサマリー」ページで、データ・ソースの名前をクリックします。

3. 「data_source_nameの設定」→「構成」→「一般」ページで、localDSなどの「JNDI名」の値を検索します。JTAを使用している場合は、persistence.xmlの<jta-data-source>と名前が一致する必要があります。

4. 「data_source_nameの設定」→「構成」→「接続プール」ページで、これらの設定を確認します。

- 「URL」の値は、persistence.xmlのjavax.persistence.jdbc.urlの値、たとえばjdbc:oracle:thin:@127.0.0.1:1521:XEと一致する必要があります。

- 「ドライバ・クラス名」の値は、persistence.xmlのjavax.persistence.jdbc.driverの値、たとえば(JTAデータ・ソースの場合は)oracle.jdbc.xa.client.OracleXADataSourceと一致する必要があります。

次の例は、ドメインのconfig.xmlファイルとアプリケーションのpersistence.xmlファイルで共有する必要がある値を示しています。

例2-6 サーバー・ドメインのconfig.xmlファイル

...
<domain...>
<jdbc-system-resource>
<name>localJTA</name>
<target>AdminServer,ManagedServer_1,ManagedServer_2</target>
<descriptor-file-name>jdbc/localJTA-4636-jdbc.xml</descriptor-file-name>
</jdbc-system-resource>
</domain>

2.3.8 タスク8: Oracleデータベースの高度な機能を使用するためのドメインの拡張

Oracle SpatialおよびOracle XDBマッピングの機能を(スタンドアロンのOracle WebLogic ServerとOracle JDeveloperに統合されたWebLogic Serverの両方で)完全にサポートするには、それぞれtoplink-spatial-template.jarおよびtoplink-xdb-template.jarを使用してWebLogic Serverドメインを拡張し、Oracle SpatialとXDBをサポートする必要があります。

WebLogic Serverドメインを拡張するには、次の手順を実行します。

1. toplink-spatial-template.jarファイル(Oracle Spatialのサポート用)とtoplink-xdb-template.jarファイル(Oracle XDBのサポート用)を次の場所からダウンロードします。

- http://download.oracle.com/otn/java/toplink/111110/toplink-spatial-template.jar

- http://download.oracle.com/otn/java/toplink/111110/toplink-xdb-template.jar

2. 表2-3および表2-4に示されているように、ファイルをコピーします。

表2-3 Oracle Spatialをサポートするためのファイル

ファイル

コピー元

目的

sdoapi.jar

ORACLE_DATABASE_HOME/md/jlib

WL_HOME/server/lib

表2-4 Oracle XDBをサポートするためのファイル

ファイル

コピー元

目的

xdb.jar

ORACLE_DATABASE_HOME/rdbms/jlib

WL_HOME/server/lib

xml.jar

ORACLE_DATABASE_HOME/lib

WL_HOME/server/lib

xmlparserv2.jar

ORACLE_DATABASE_HOME/lib

WL_HOME/server/lib

3. 構成ウィザード(WL_HOME/common/bin/config.sh (または.bat))を起動します。

4. 「既存のWebLogicドメインの拡張」を選択します。

5. WebLogic Serverドメインを参照して選択します。

6. 「既存の拡張テンプレートを使用してドメインを拡張する」を選択します。

7. 必要なテンプレートJARを参照して選択します(Oracle Spatialの場合はtoplink-spatial-template.jar、Oracle XDBの場合はtoplink-xdb-template.jar)。

8. ウィザードの残りのページを完了します。

WebLogic Serverドメイン・テンプレートの使用方法の詳細は、『Oracle Fusion Middlewareドメイン・テンプレート・リファレンス』を参照してください。

2.3.9 タスク10: WebLogic Serverの起動とアプリケーションのデプロイ

WebLogic Serverへのデプロイの詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverへのアプリケーションのデプロイ』を参照してください。『Oracle Fusion Middleware Oracle Application Development FrameworkのためのFusion開発者ガイド』のFusion Webアプリケーションのデプロイに関する項も参照してください。

2.3.10 タスク11: アプリケーションの実行

デプロイされたアプリケーションをWebLogic管理コンソールから起動する手順の詳細は、管理コンソール・オンライン・ヘルプのデプロイされたエンタープライズ・アプリケーションの起動と停止に関する項を参照してください。

2.3.11 タスク12: WebLogic Serverの永続性設定の構成および監視

WebLogic Server管理コンソールでは、永続性ユニットを構成して、永続性ユニットのJTAおよび非JTAのデータ・ソースを構成できます。次に方法を説明します。

1. まだ行っていない場合は、管理コンソールのチェンジ・センターで「ロックして編集」をクリックします。

2. 管理コンソールの左ペインで、「デプロイメント」を選択します。

3. 右ペインで、構成するアプリケーションまたはモジュールを選択します。

4. 「構成」を選択します。

5. 「永続性」を選択します。

6. 構成する永続性ユニットを表から選択します。

7. 構成ページのプロパティを確認および編集します。ページのヘルプは、管理コンソールの上部の「ヘルプ」リンクをクリックすれば表示されます。
次のようなプロパティを表示できます。

- 名前

- プロバイダ

- 説明

- トランザクション・タイプ

- データ・キャッシュ・タイムアウト

- バッチ・サイズのフェッチ

- デフォルト・スキーマ名

- 名前

- persistence.xmlファイルに定義されている永続性ユニット・プロパティの値、たとえば、eclipselink.session-name、eclipselink.logging.levelおよびeclipselink.target-server。

永続性ユニットのトランザクション・データ・ソースと非トランザクション・データ・ソースに関連する属性も「データ・ソース」構成ページに設定できます。

8. これらの変更を有効にするために、管理コンソールの「チェンジ・センター」で「変更のアクティブ化」をクリックします。

管理コンソールの永続性の操作に関する他のヘルプ・トピックへのリンクについては、管理コンソール・オンライン・ヘルプの目次で「永続性(Persistence)」を検索してください。

2.4 その他の参照資料

Oracle TopLinkおよびOracle WebLogic Serverの詳細は、次のリンクを参照してください。

- EclipseLink Documentation Center
http://wiki.eclipse.org/EclipseLink/Documentation_Center

- 次のようなOracle WebLogic Serverドキュメント
Oracle Fusion Middleware Oracle WebLogic Serverインフォメーション・ロードマップ

2.4.1 コード・サンプル

関連情報は、次のEclipseLinkの例を参照してください。

- http://wiki.eclipse.org/EclipseLink/Examples/JPA/WebLogic_Web_Tutorial

- http://wiki.eclipse.org/EclipseLink/Examples/JPA/WLS_AppScoped_DataSource

- http://wiki.eclipse.org/EclipseLink/Examples/Distributed

2.4.2 関連Javadoc

詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』の次のAPIを参照してください。

- org.eclipse.persistence

- org.eclipse.persistence.jpa.PersistenceProvider

- org.eclipse.persistence.services.mbean

3 GlassFish ServerでのTopLinkの使用

この章では、Oracle GlassFish ServerにデプロイされたTopLink Java Persistence API (JPA) 2.0のアプリケーションに対してTopLinkを永続性プロバイダとして使用する方法を説明します。

この章には次の項が含まれます:

- 3.1項「TopLinkおよびGlassFish Serverの理解」

- 3.2項「開始時の必要事項」

- 3.3項「主なタスク」

- 3.4項「その他の参照資料」

3.1 TopLinkおよびGlassFish Serverの理解

Oracle GlassFish Serverは、Java Platform, Enterprise Edition (Java EE)仕様のリファレンス実装です。GlassFish Server Open Source Editionを使用してビルドされたOracle GlassFish Serverは、本番にすぐ使用できる柔軟で軽量なJava EEプラットフォームを提供します。

GlassFish ServerはOracle Fusion Middlewareアプリケーション・グリッド・ポートフォリオの一部であり、エンタープライズJavaの最新実装を使用した軽量インフラストラクチャを必要とするアプリケーションに最適です。GlassFish Serverは、Oracle Fusion Middlewareのより広範なポートフォリオおよび大規模なエンタープライズ・アプリケーションを実行するように設計されたOracle WebLogic Serverを補完する製品です。

3.1.1 GlassFish ServerでTopLinkを使用する利点

TopLinkサポートを追加することにより、GlassFishプラットフォームのアプリケーション開発者が、Java Persistence API (JPA) 2.0仕様に準拠してJavaとデータ・ソースを完全に統合できるようになります。TopLinkでは、理想的なアプリケーション設計またはデータの整合性を損わずに、Javaアプリケーションをすべてのデータ・ソースと統合できます。また、TopLinkを使用すれば、GlassFishプラットフォームのアプリケーションで、リレーショナル・データベースまたはXMLデータ・ソースをリポジトリとして使用して、ビジネス・ドメイン・オブジェクトを格納(永続化)および取得できるようになります。

GlassFish Serverでは他の永続性プロバイダを使用でき、TopLinkは他のアプリケーション・サーバーで使用できるので、GlassFish ServerをTopLinkとともに使用すると、次のような多くの利点があります。

- TopLinkはすべてのGlassFish Serverディストリビューションに含まれており、デフォルトのJPAプロバイダになります。

- TopLinkでは、GlassFish Serverで動作するアプリケーションでOracle Coherenceのキャッシュを使用できます。Coherenceは、データ・キャッシング、データ・レプリケーションおよび分散コンピューティング・サービスを提供するJavaベースのインメモリー・データグリッド製品です。TopLinkには、デプロイされたアプリケーションでCoherenceデータ・キャッシュを使用し、オブジェクトからリレーショナルへの永続化フレームワークとしてTopLink Gridを組み込む機能が含まれています。この製品の使用方法は、このドキュメントでは説明しません。詳細は、『Oracle Fusion Middleware Oracle TopLinkのためのCoherence Grid統合ガイド』を参照してください。

- GlassFish ServerのTopLinkロギング統合では、包括的な統合ロギング・インフラストラクチャが実現されています。

- GlassFish Serverは、StrutsとJavaServer Faces (JSF)に基づいたエンド・ツー・エンドのJava EEフレームワークであるOracle Application Framework (ADF)をサポートしています。ADFでは、インフラストラクチャ・サービスおよび視覚的で宣言的な開発エクスペリエンスを実現することにより、アプリケーション開発が簡素化されています。TopLinkおよびADFをともに使用することにより、完全なJava EEアプリケーション・インフラストラクチャが実現されます。ADFの使用方法は、このドキュメントでは説明しません。『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』を参照してください。

3.1.2 Fusion Middleware製品に対するGlassFish ServerとTopLinkの関係

図3-1は、他のOracle製品に対するGlassFish ServerとTopLinkの関係および使用方法を示しています。TopLinkは永続性プロバイダとして使用できます。データ・キャッシング、データ・レプリケーションおよび分散コンピューティング・サービスには、Oracle Coherenceを(TopLink Gridの統合を介して)使用します。GlassFishはアプリケーション・サーバーとして使用し、データの永続化にはOracleデータベースを使用します。

注意:

Oracle CoherenceおよびTopLink Gridについては、このドキュメントでは説明しません。Coherenceの詳細は、Oracle Coherence開発者ガイドを参照し、Coherenceの他のドキュメントについては、リンクを参照してください。TopLink Gridの詳細は、『Oracle Fusion Middleware Oracle TopLinkのためのCoherence Grid統合ガイド』を参照してください。

図3-1 Fusion Middlewareスタックの他の製品に対するGlassFish ServerとTopLinkの関係

図3-1「Fusion Middlewareスタックの他の製品に対するGlassFish ServerとTopLinkの関係」の説明

3.2 開始時の必要事項

このドキュメントは、次の製品およびツールに基づいていますが、原則は、サポートされているすべてのデータベースまたは開発環境に適用できます。後の項で特記されている場合以外、ソフトウェアはすでにインストールされているものと仮定しています。

GlassFish Serverに対して、TopLink アプリケーションを開発およびデプロイするには、次のものが必要です。

- GlassFish Serverバージョン3.1.1。
詳細およびダウンロードは、Oracle Technology Networkのhttp://www.oracle.com/technetwork/middleware/glassfish/overview/index.htmlを参照してください。

- EclipseLinkソフトウェア・ディストリビューション2.3.0。
詳細およびダウンロードは、EclipseLink Webサイトのhttp://www.eclipse.org/eclipselink/を参照してください。

- Oracle、Oracle Express、MySQLなどのJDBC準拠データベース。
Oracleデータベースについては、http://www.oracle.com/technetwork/database/enterprise-edition/overview/index.htmlを参照してください。

Oracle Express Editionについては、http://www.oracle.com/technetwork/database/express-edition/overview/index.htmlを参照してください。

MySQLについては、http://www.oracle.com/us/products/mysql/index.htmlを参照してください。

- 必須ではありませんが、Java EE開発環境(IDE)を開発に使用すると便利です。たとえば、JDeveloper、Oracle Enterprise Pack for Eclipse (OEPE)およびOracle NetBeansにはすべて、高度なJava EE開発ツールが用意されています。
JDeveloperについては、http://www.oracle.com/technetwork/developer-tools/jdev/downloads/index.htmlを参照してください。

OEPEについては、http://www.oracle.com/technetwork/developer-tools/eclipse/overview/index.htmlを参照してください。

NetBeansについては、http://www.oracle.com/us/products/tools/050845.htmlを参照してください。

3.3 主なタスク

TopLink JPAアプリケーションをGlassFish Serverで実行するには、サーバーを構成して、サーバーとアプリケーションの特定の設定を調整する必要があります。これらについては、次のタスクで説明します。

- タスク1: GlassFish Serverに対するObject-XML (JAXB)サポートの追加(オプション)

- タスク2: データソースの設定

- タスク3: persistence.xmlファイルの作成

- タスク4: JPA用のGlassFish Serverの設定

- タスク5: アプリケーションの作成

- タスク6: GlassFish Serverに対するアプリケーションのデプロイ

- タスク7: アプリケーションの実行

- タスク8: アプリケーションの監視

3.3.1 タスク1: GlassFish Serverに対するObject-XML (JAXB)サポートの追加(オプション)

Oracle TopLinkはGlassFishのディストリビューションに含まれています。GlassFishサーバーのインストールおよび構成の手順は、次のURLに説明されています。

http://glassfish.java.net/docs/3.1.1/installation-guide.pdf

TopLinkのモジュールは、modulesディレクトリの個別のJARファイルとして表示されます。

* \glassfish\modules
...
o org.eclipse.persistence.antlr.jar
o org.eclipse.persistence.asm.jar
o org.eclipse.persistence.core.jar
o org.eclipse.persistence.jpa.jar
o org.eclipse.persistence.jpa.modelgen.jar
o org.eclipse.persistence.oracle.jar
...

注意:

- Coherenceのキャッシュをサポートするtoplink-grid.jarファイルを使用できるのは、Oracle Coherenceのライセンスを購入した場合のみです。toplink-grid.jarファイルで提供される機能の詳細は、Oracle Coherence Oracle TopLinkのためのCoherence Grid統合ガイドを参照してください。

- org.eclipse.persistence.oracle.jarファイルはGlassFishで使用可能で、TopLinkに対するOracleデータベース固有の機能を提供します。このファイルは、Oracleデータベースに対して実行されるアプリケーションのみに対して使用されます。

Object-XML (JAXBサポートまたはMOXyとも呼ばれます)は、XMLスキーマにJavaクラスをバインドできるようにするTopLinkコンポーネントです。GlassFish Serverに対するObject-XMLサポートの追加はオプションです。多くのアプリケーションは、Object-XMLサポートを追加しなくてもGlassfish Serverで実行できます。

Object-XMLはGlassFish 3.1.1とともには配布されません。Object-XMLバンドルを入手するには、EclipseLinkリリース2.3.0ソフトウェア・ディストリビューションから入手する必要があります。

1. EclipseLinkリリース2.3.0ソフトウェア・ディストリビューションをダウンロードしてオープンします。

2. Object-XMLバンドルorg.eclipse.persistence.moxy_2.3.0.v20110604-r9504.jarをディストリビューションから.../glassfish/modulesフォルダにコピーします。

3. .../glassfish/domainsフォルダの各ドメインで、osgi-cacheサブフォルダの内容を削除します。

4. GlassFish Serverがすでに実行中の場合は再起動します。

注意:

リリース3.1.2以降、Object-XML (MOXy)はGlassFish Serverとともに提供されるようになりました。

3.3.2 タスク2: データソースの設定

Java EEアプリケーションのJDBCリソースとしてOracleデータベースを構成するには、次のタスクを実行します。

1. GlassFish ServerへのOracleデータベースのJDBCドライバの統合

2. リソースに対するJDBC接続プールの作成

3. JDBCリソースの作成

3.3.2.1 GlassFish ServerへのOracleデータベースのJDBCドライバの統合

JDBCドライバを統合するには、JARファイルをドメインにコピーしてから、ドメインおよびインスタンスを再起動し、ドライバを使用可能にします。

1. JDBCドライバのJARファイルをドメインのlibサブディレクトリに、次のようにコピーします。

cd /home/gfuser/glassfish3
cp oracle-jdbc-drivers/ojdbc6.jar glassfish/domains/domain1/lib

GlassFish Serverを再起動する必要はありません。ドライバは動的にピックアップされます。

TopLinkで提供されるOracleデータベース固有の拡張機能をアプリケーションが使用している場合は、ドライバをlib/extディレクトリにコピーする必要があります。詳細は、Oracle GlassFish Server 3.1アプリケーション開発ガイドのOracleデータベースの拡張機能に関する項を参照してください。

http://download.oracle.com/docs/cd/E18930_01/html/821-2418/gbxjh.html#giqbi

2. GlassFishの管理コンソールまたはコマンド・ラインを使用して、ドメインのインスタンスを再起動し、インスタンスがJDBCドライバを使用できるようにします。
GlassFish Server管理コンソールを使用するには:

GlassFish Server管理コンソールで、「クラスタ」ノードをオープンします。クラスタのノード選択して、「一般情報」ページで、「インスタンス」タブをクリックします。再起動するインスタンスを選択します。詳細は、GlassFish管理コンソール・オンライン・ヘルプのクラスタ化されたGlassFish Serverインスタンスの起動に関する項を参照してください。

コマンド・ラインを使用するには:

restart-instanceサブコマンドを実行して、インスタンスを再起動します。これらのコマンドでは、インスタンスの名前がpmd-i1およびpmd-i2である仮定しています。

restart-instance pmd-i1
restart-instance pmd-i2

3.3.2.2 リソースに対するJDBC接続プールの作成

JDBC接続プールは、GlassFish Server管理コンソールまたはコマンド・ラインから作成できます。

GlassFish Server管理コンソールを使用するには:

GlassFish Server管理コンソールで、「共通タスク」ノードを選択して、「共通タスク」ページの「新規JDBC接続プールの作成」ボタンをクリックします。プールの名前、リソース・タイプ、データベース・プロバイダの名前、データ・ソースとドライバ・クラスの名前、および他の詳細を指定します。詳細は、GlassFish管理コンソール・オンライン・ヘルプのJDBC接続プールの作成に関する項を参照してください。

コマンド・ラインを使用するには:

1. create-jdbc-connection-poolサブコマンドを使用して、JDBC接続プールを作成し、データベース接続の値を指定します。このコマンドでは、URLプロパティ値の前に2つのバック・スラッシュ(\\)を使用していることに注意してください。これらのバック・スラッシュにより、コロンがプロパティと値のペアのセパレータとしてではなく、プロパティ値の一部として解釈されるようになります。次に例を示します。

create-jdbc-connection-pool
--datasourceclassname oracle.jdbc.pool.OracleDataSource
--restype javax.sql.DataSource
--property User=coreora10g\\:Password=coreora10g\\:url=jdbc\\:oracle\\:thin\\:@asqe-db1.us.oracle.com\\:1521\\:asqedb
poolbvcallbackbmt

2. データベースへの接続を確認します。

ping-connection-pool pool_name

3.3.2.3 JDBCリソースの作成

GlassFish Server管理コンソールを使用してJDBCリソースを作成することも、コマンド・ラインを使用することもできます。

GlassFish Server管理コンソールを使用するには:

GlassFish Server管理コンソールで、「リソース」ノード、「JDBC」ノード、「JDBCリソース」ノードを選択して、「JDBCリソース」ページをオープンします。一意のJNDIリソース名を指定して、リソースを接続プールと関連付けます。詳細は、GlassFish管理コンソール・オンライン・ヘルプのJDBCリソースの作成に関する項を参照してください。

コマンド・ラインを使用するには:

create-jdbc-resourceサブコマンドを使用して、JDBCリソースを作成し、JNDIルックアップによってアプリケーションがJDBCリソースを見つけられるような名前を付けます。次に例を示します。

create-jdbc-resource --connectionpoolid poolbvcallbackbmt jdbc/bvcallbackbmt

3.3.3 タスク3: persistence.xmlファイルの作成

例3-1に、TopLinkのデフォルト永続性プロバイダorg.eclipse.persistence.jpa.PersistenceProviderを指定するpersistence.xmlのサンプル・ファイルを示します。このファイルの詳細は、EclipseLinkドキュメントの『Configuring Persistence Units Using persistence.xml』を参照してください。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Configuration/JPA/persistence.xml

デフォルトの永続性プロバイダを使用している場合は、EclipseLinkドキュメントの『How to Use EclipseLink JPA Extensions for JDBC Connection Communication』にリストされている追加のデータベース・プロパティを指定できます。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#How_to_Use_EclipseLink_JPA_Extensions_for_JDBC_Connection_Communication

ファイルに入力する値のいくつかは、次に示すように、クラスタ、接続および接続プールのプロパティをGlassFish Serverに定義したときに選択した値と一致する必要があります。

JDBCデータソース・プロパティ:

- 名前: データ・ソースの名前。通常この名前は、次のJNDI名と同じです。たとえば、jdbc/bvcallbackbmtと指定します。

- JNDI名: このデータ・ソースがバインドされる場所へのJNDIパス。これは、persistence.xmlの<jta-data-source>要素の値と同じにする必要があります。たとえば、jdbc/bvcallbackbmtのように指定します。

- データベース・タイプ: Oracle

- データベース・ドライバ: (デフォルト) インスタンス接続用のOracleのドライバ(Thin XA)。バージョン: 9.0.1以降

接続プロパティ:

- データベース名: データベースの名前。たとえば、Oracle Database Expressのサンプルの場合はXEです。

- ホスト名: データベース・サーバーのIPアドレス。たとえば、ローカルにホストされているデータベースの場合は127.0.0.1です。

- ポート: データベース・サーバーが接続リクエストをリスニングするポート番号。たとえば、Oracle Database Express 11gのデフォルトは1521です。

- データベース・ユーザー名: データベース接続を作成するために使用するデータベース・アカウントのユーザー名。たとえば、Oracle Database Express 11gのサンプルの場合はhrです。

- パスワード: 使用するパスワード。

ターゲットの選択:

- サーバー/クラスタ: データ・ソースをデプロイする管理サーバー、管理対象サーバーまたはクラスタを選択します。1つ以上を選択できます。

例3-1のpersistence.xmlのサンプル・ファイルでは、永続性プロバイダ、JTAデータ・ソースおよびロギングの詳細を定義するプロパティを強調表示しています。この例では、ロギング・レベルはFINEに設定されています。このレベルでは、EclipseLinkによって生成されるSQLコードはserver.logにロギングされます。これらのプロパティの詳細は、次の項を参照してください。

- 3.3.3.1項「永続性プロバイダの指定」

- 3.3.3.2項「Oracle Databaseの指定」

- 3.3.3.3項「ロギングの指定」

例3-1 persistence.xmlのサンプル・ファイル

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="pu1" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/bvcallbackbmt</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.ddl-generation"
value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>

3.3.3.1 永続性プロバイダの指定

永続性プロバイダでは、JPAの実装を定義します。これは、persistence.xmlファイルのprovider要素に定義されています。永続性プロバイダはベンダー固有のものです。Oracle TopLinkの永続性プロバイダはorg.eclipse.persistence.jpa.PersistenceProviderです。

3.3.3.2 Oracleデータベースの指定

データベース接続の詳細はpersistence.xmlファイルに指定します。GlassFish Serverのデフォルトでは、バンドルされている、jdbc/__defaultという名前のJava DB (Derby)データベースが使用されます。Oracleデータベースなどのデフォルト以外のデータベースを使用するには、jta-data-source要素に値を指定するか、transaction-type要素にRESOURCE_LOCALを設定して、non-jta-data-source要素に値を指定します。

デフォルトの永続性プロバイダorg.eclipse.persistence.jpa.PersistenceProviderを使用している場合は、接続メタデータに基づいて、プロバイダがデータベース・タイプの自動検出を試みます。このデータベース・タイプを使用して、検出されたデータベース・タイプに固有のSQL文が発行されます。オプションのeclipselink.target-databaseプロパティを指定すれば、データベース・タイプが正しいことを保証できます。

GlassFish Server用のpersistence.xmlファイルにデータベース・プロパティを指定する方法の詳細は、Oracle GlassFish Server 3.1アプリケーション開発ガイドのデータベースの指定に関する項を参照してください。

http://download.oracle.com/docs/cd/E18930_01/html/821-2418/gbwmj.html

このトピックでは、(Java SEモードで)EJBコンテナ外部のJava Persistence APIを使用する方法についても説明します。eclipselink.jdbc.*プロパティは、GlassFish ServerをJava SEモードで使用する場合のみに指定します。次に例を示します。

...
<property name="eclipselink.jdbc.url" value="jdbc:oracle:thin://localhost:1521:xe;retrieveMessagesFromServerOnGetMessage=true;create=true;"/>
<property name="eclipselink.jdbc.user" value="APP"/>
<property name="eclipselink.jdbc.password" value="APP"/>
...

Oracleデータベースの一般的な接続の詳細を次に示します。

- ドライバ: oracle.jdbc:OracleDriver

- SID (データベース名): xe

- ホスト: localhost

- ポート番号: 1521

- ユーザー名: データベース・ユーザーの名前

- パスワード: データベース・パスワード

- 接続URL: jdbc:oracle:thin:@localhost:1521:xe

JDBCデータソース接続のこれらのプロパティおよび他の拡張機能の詳細は、EclipseLinkドキュメントの『Using EclipseLink JPA Extensions for JDBC』およびPersistenceUnitProperties APIを参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_JDBC

『Oracle Fusion Middleware Java API Reference for EclipseLink』のPersistenceUnitPropertiesに関する項も参照してください。

3.3.3.3 ロギングの指定

ロギングはJPA仕様の一部ではありませんが、TopLinkにはロギング・ユーティリティが用意されています。そのため、ログで提供される情報はTopLink JPA固有のものです。TopLinkでロギングを有効にすれば、次の情報を表示できます。

- 構成の詳細

- デバッグを容易にするための情報

- データベースに送信されるSQL

ロギングはpersistence.xmlファイルに指定できます。TopLinkのロギング・プロパティでは、ロギングのレベル、およびログの出力をファイルまたは標準出力のどちらにするかを指定できます。ロギング・ユーティリティは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"/>

TopLinkのロギング・ユーティリティはプラガブルで、java.util.loggingなどの数種類のロギング統合がサポートされています。java.util.loggingを有効にするには、eclipselink.logging.loggerプロパティを次のように設定します。

<property name="eclipselink.logging.logger" value="JavaLogger"/>

GlassFish Server内でTopLinkを実行している間は、デフォルトでJavaLoggerを使用するようにGlassFishによって構成されます。ログは常にGlassFishのserver.logファイルにリダイレクトされます。詳細は、Oracle GlassFish Server 3.1アプリケーション開発者ガイドのログ・レベルの設定に関する項を参照してください。

http://download.oracle.com/docs/cd/E18930_01/html/821-2418/gdpwu.html

TopLinkのロギングおよびロギング・ユーティリティで使用可能なロギング・レベルの詳細は、EclipseLinkドキュメントの『EclipseLink/Examples/JPA/Logging』を参照してください。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging

3.3.4 タスク4: JPA用のGlassFish Serverの設定

GlassFish Serverアプリケーション開発ガイドには、JPAを利用するアプリケーションを実行するGlassFishサーバーを設定する際のサーバー固有の考慮事項が説明されています。

http://download.oracle.com/docs/cd/E18930_01/html/821-2418/gbxjk.html

アプリケーション開発ガイドには、次のトピックの詳細が説明されています。

- データベースの指定に関する項には、データベース接続プロパティの詳細が説明されています。

- 追加のデータベース・プロパティに関する項には、デフォルトの永続性プロバイダを使用している場合のデータベース・プロパティの詳細が説明されています。

- キャッシュの構成に関する項には、デフォルトの永続性プロバイダのキャッシング・プロパティの詳細が説明されています。

- ロギング・レベルの設定に関する項には、デフォルトの永続性プロバイダのロギング・プロパティの設定の詳細が説明されています。

3.3.5 タスク5: アプリケーションの作成

TopLinkをJPAプロバイダとして使用するアプリケーションを作成するには、Java EE開発環境を開発に使用すると便利です。たとえば、Oracle JDeveloper、Oracle Enterprise Pack for Eclipse (OEPE)およびOracle NetBeansにはすべて、TopLinkのサポートを含む高度なJava EE開発ツールが用意されています。Oracle TopLinkコンセプトのTopLinkの開発ツールに関する項を参照してください。

アプリケーション開発のガイドラインについては、Oracle GlassFish Server 3.1アプリケーション開発ガイドのJava永続性APIの使用の章の次のトピックを参照してください。

http://download.oracle.com/docs/cd/E18930_01/html/821-2418/gbxjk.html

3.3.6 タスク6: GlassFish Serverに対するアプリケーションのデプロイ

GlassFish Serverへのデプロイの詳細は、GlassFish Server管理コンソール・オンライン・ヘルプのアプリケーションまたはモジュールのデプロイに関する項、エンタープライズ・アプリケーションのデプロイに関する項、およびWebアプリケーションのデプロイに関する項を参照してください。Oracle GlassFish Server 3.1アプリケーション・デプロイメント・ガイドも参照してください。

http://download.oracle.com/docs/cd/E18930_01/html/821-2417/index.html

3.3.7 タスク7: アプリケーションの実行

デプロイされたアプリケーションをGlassFish管理コンソールから起動する手順の詳細は、GlassFish Server管理コンソール・オンライン・ヘルプのアプリケーション・クライアントの起動に関する項、およびアプリケーションの起動に関する項を参照してください。

3.3.8 タスク8: アプリケーションの監視

GlassFish Serverには、アプリケーションのヘルスおよびパフォーマンスを追跡するモニタリング・サービスが用意されています。コンソールからアプリケーションをモニタリングする方法の詳細は、GlassFish Server管理コンソール・オンライン・ヘルプのモニタリングに関する項、およびデータのモニタリングに関する項を参照してください。コマンド・ラインからアプリケーションをモニタリングする方法の詳細は、Oracle GlassFish Server 3.1アプリケーション・デプロイメント・ガイドのモニタリング・サービスの管理に関する項を参照してください。

http://download.oracle.com/docs/cd/E18930_01/html/821-2416/ablur.html

3.4 その他の参照資料

Oracle TopLinkおよびOracle GlassFish Serverの詳細は、次のリンクを参照してください。

- EclipseLinkドキュメント
http://www.eclipse.org/eclipselink/

- Oracle GlassFish Server 3.1アプリケーション・デプロイメント・ガイド
http://download.oracle.com/docs/cd/E18930_01/html/821-2417/index.html

- Oracle GlassFish Serverアプリケーション開発ガイド
http://download.oracle.com/docs/cd/E18930_01/html/821-2418/gbxjk.html

- Oracle GlassFish Server 3.1 - 3.1.1ドキュメント・ライブラリ
http://download.oracle.com/docs/cd/E18930_01/index.html

4 コンポジット永続性ユニットによる複数データベースの使用

TopLinkでは、コンポジット永続性ユニットを使用して、(エンティティ・タイプの独自のセットがそれぞれに設定された)複数の永続性ユニットを単一の永続性コンテキストとして公開できます。コンポジット永続性ユニットの一部である個々の永続性ユニットを、コンポジット・メンバー永続性ユニットと呼びます。

この章では、次の項目について説明します。

- 4.1項「コンポジット永続性ユニットの理解」

- 4.2項「主なタスク」

- 4.3項「その他の参照資料」

4.1 コンポジット永続性ユニットの理解

コンポジット永続性ユニットでは、次のことを行えます。

- コンポジット永続性ユニット内の任意のエンティティ間の関係のマッピング

- 複数のデータベースおよび様々なデータ・ソースにストアされているエンティティへのアクセス

- エンティティの完全なセット全体に対する問合せおよびトランザクションの容易な実行

例4-1は、1つのコンテキストから2つの異なるデータベースにデータを永続化する方法を示しています。

例4-1 複数のデータベースの使用

em.persist(new A(..));
em.persist(new B(..));
// You can insert A into database1 and insert B into database2.
// The two databases can be from different vendors.

em.flush();

図4-1 単純なコンポジット永続性ユニット

図4-1「単純な複数永続性ユニット」の説明

図4-1は、単純な複数永続性ユニットを示しています。EntityManagerは、(Persistence.createEntityManagerFactoryメソッドにそれらを渡して)次の2つの複合メンバー永続性ユニットを含む複合永続性ユニットをインスタンス化します。

- クラスAは、member1.jarにあるmemberPu1という名前の永続性ユニットによってマップされています。

- クラスBは、member2.jarにあるmemberPu2という名前の永続性ユニットによってマップされています。

4.1.1 コンポジット永続性ユニットの要件

コンポジット永続性ユニットを使用する際には、次の要件に注意してください。

- 各コンポジット・メンバー永続性ユニットの名前は、コンポジット内で一意である必要があります。

- 永続性ユニット全体に対応するtransaction-typeおよび他のプロパティ(ターゲット・サーバー、ロギング・トランザクションなど)はコンポジット永続性ユニットで定義してください。そうしないと、アプリケーションはデフォルトを使用します。

- すべてのコンポジット・メンバー永続性ユニットで、同じtransaction-typeをコンポジット永続性ユニットとして使用する必要があります。

4.2 主なタスク

この項には、次の項目が含まれます。

- タスク1: コンポジット永続性ユニットの構成

- タスク2: コンポジット永続性ユニットの使用

- タスク3: コンポジット永続性ユニットのデプロイ

4.2.1 タスク1: コンポジット永続性ユニットの構成

コンポジット永続性ユニットは通常の永続性要素なので、persistence.xmlファイルが必要です。例4-2に、persistence.xmlのサンプル・ファイルを示します。

例4-2 コンポジット永続性ユニットのpersistence.xmlファイル

<persistence 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 persistence_1_0.xsd" version="1.0">
<persistence-unit name="compositePu" transaction-type="JTA">
<provider>
org.eclipse.persistence.jpa.PersistenceProvider
</provider>

<jar-file>member1.jar</jar-file>
<jar-file>member2.jar</jar-file>
<properties>
<property name="eclipselink.composite-unit" value="true"/>
<property name="eclipselink.target-server" value="WebLogic_10"/>
</properties>
</persistence-unit>
</persistence>

<property name="eclipselink.composite-unit" value="true"/>プロパティを使用して、永続性ユニットをコンポジットとして指定します。

<jar-file>要素を使用して、コンポジット・メンバー永続性ユニットを含むJARファイルを指定します。コンポジット永続性ユニットには、指定したJARファイルで見つかったすべての永続性ユニットが含まれます。

4.2.2 タスク2: コンポジット永続性ユニットの使用

コンポジット永続性ユニットは他の永続性ユニットと同様に使用できます。次に示すように、EntityManagerを注入できます。

@PersistenceUnit(unitName="compositePu")
EntityManagerFactory entityManagerFactory;

@PersistenceUnit(unitName="compositePu")
EntityManager entityManager;

また、手動で作成することもできます。

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("compositePu", properties);

4.2.3 タスク3: コンポジット永続性ユニットのデプロイ

複数の永続性ユニットをデプロイするには、同じクラス・ローダーのすべてのJAR (コンポジットおよびそのメンバー)をデプロイします。

- Oracle WebLogic Serverにデプロイする際には、JARをEARファイルにパッケージ化します。

- スタンドアロン・アプリケーションとして実行する際には、JARをクラス・パスに追加します。

重要な情報および制限は、4.1.1項「コンポジット永続性ユニットの要件」を参照してください。

4.3 その他の参照資料

コンポジット永続性ユニットに関する次のような追加情報は、EclipseLinkドキュメントのhttp://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Composite_Persistence_Unitsを参照してください。

- コンポジット永続性ユニットの制限

- 相互の依存関係が含まれるコンポジット・メンバー永続性ユニットの構成

- コンポジット永続性ユニットおよびコンポジット・メンバー永続性ユニットで使用されるすべての永続性ユニット・プロパティ

- コンポジット永続性ユニットEntityManagerFactoryを作成中に、Persistence.createEntityManagerFactoryメソッドでコンポジット・メンバー永続性ユニットに永続性ユニット・プロパティを渡す方法

- コンポジット永続性ユニットおよびコンポジット・メンバー永続性ユニットで使用されるすべてのエンティティ・マネージャ

- コンポジット永続性ユニットEntityManagerFactoryのemf.createEntityManagerメソッドでコンポジット・メンバー永続性ユニットにエンティティ・マネージャ・プロパティを渡す方法

4.3.1 Javadoc

詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』の次のAPIを参照してください。

- PersistenceUnitPropertiesクラス

- Persistence.createEntityMangerクラス

- EntityManagerFactoryインタフェース

5 クラスタ内のTopLinkアプリケーションのスケーリング

この章では、クラスタ化されたアプリケーション・サーバー環境でスケーラビリティを確保しながらTopLinkアプリケーションを構成する手順を説明します。この手順は一般的なもので、どのアプリケーション・サーバー環境にも適用できますが、WebLogicサーバーおよびGlassFishサーバーには、追加の内容が用意されています。必要に応じて、ベンダーのドキュメントを参照してください。

この章には次の項が含まれます:

- 5.1項「クラスタ内のTopLinkアプリケーションのスケーリングの理解」

- 5.2項「主なタスク」

- 5.3項「その他の参照資料」

5.1 クラスタ内のTopLinkアプリケーションのスケーリングの理解

クラスタ化されたアプリケーション・サーバー環境にデプロイされたTopLinkアプリケーションは、クラスタのスケーラビリティ、負荷分散およびフェイルオーバーを利用できます。これらの機能は、TopLinkアプリケーションの可用性を高め、アプリケーションの需要拡大に伴ってスケーリングできます。TopLinkのアプリケーションは、クラスタ化されたサーバー環境でも、スタンドアロンのサーバー環境と同様にデプロイされます。ただし、クラスタ化された環境では、キャッシュの整合性をTopLinkのアプリケーションで考慮する必要があります。

TopLinkでは、オブジェクトおよびその関係を取得する際にデータベースへのアクセスを回避する共有(L2)オブジェクト・キャッシュを利用します。このキャッシュはデフォルトで有効になり、アプリケーションのパフォーマンスが向上します。クラスタ化された環境でキャッシングを使用すると、1つのサーバーで行われた変更が、他のサーバーでキャッシュされているオブジェクトに反映されないために、整合性の問題(失効データなど)が発生する場合があります。キャッシュの整合性が問題になるのは、頻繁に更新されるオブジェクトのみです。読取り専用のオブジェクトは、キャッシュの整合性の影響を受けません。キャッシングの詳細は、EclipseLinkの次のドキュメントを参照してください。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Caching_Overview

キャッシュの整合性に対処するには、次のように様々な方法があります。

- 分散キャッシングを使用します。TopLinkには、分散環境で運用した場合に発生するキャッシュの整合性の問題の多くに対処できるOracle Coherenceとの統合が含まれています。この統合については、このドキュメントでは説明しません。詳細は、Oracle Coherence Oracle TopLinkのためのCoherence Grid統合ガイドを参照してください。

- キャッシュ・コーディネーションを使用して、クラスタ内のサーバー間で変更をブロードキャストし、変更されたオブジェクトを更新するか無効にします。

- オプティミスティック・ロックを使用して、失効オブジェクトの変更を防止し、キャッシュ内のオブジェクトの無効化をトリガーします。

- フレッシュなデータが必要な場合に、オブジェクトまたは問合せのリフレッシュを使用します。

- 共有キャッシュを無効にするか、読取り専用オブジェクトのみをキャッシュします。

5.2 主なタスク

この項のタスクでは、アプリケーション・サーバーのクラスタ環境でTopLinkアプリケーションをスケーリングできるようにするための一般的な手順を説明します。これらのタスクは、アプリケーションをデプロイする前に完了する必要があります。

この項の内容は次のとおりです。

- タスク1: キャッシュの整合性の構成

- タスク2: TopLinkの有効化の確認

- タスク3: すべてのアプリケーション・サーバーがクラスタ内にあることの確認

5.2.1 タスク1: キャッシュの整合性の構成

このタスクには、アプリケーション・サーバーのクラスタ環境にアプリケーションがデプロイされた場合に、アプリケーションが失効データを使用する可能性を少なくする様々な構成オプションが含まれています。キャッシュ・コーディネーション・オプションは、クラスタ化されたアプリケーション用に特に設計されていますが、すべてのオプションを評価し、(適用可能な場合は)一緒に使用して、アプリケーションのパフォーマンスが最高になるようなソリューションを作成します。キャッシュを適切に構成すれば、キャッシュ・コーディネーションを使用する必要がなくなる場合もあります。これらのオプションの詳細は、次を参照してください。

http://wiki.eclipse.org/Introduction_to_Cache_%28ELUG%29#Handling_Stale_Data

この項の内容は次のとおりです。

- 5.2.1.1項「共有キャッシュの無効化」

- 5.2.1.2項「キャッシュのリフレッシュ」

- 5.2.1.3項「キャッシュ有効期限の設定」

- 5.2.1.4項「オプティミスティック・ロックの設定」

- 5.2.1.5項「キャッシュ・コーディネーションの使用」

注意:

TopLinkでCoherenceをL2キャッシュとして使用できるようにするTopLinkとCoherenceの統合が提供されています。この統合については、このドキュメントでは説明しません。詳細は、Oracle Coherence Oracle TopLinkのためのCoherence Grid統合ガイドを参照してください。

5.2.1.1 共有キャッシュの無効化

アプリケーションに共有キャッシュが不要な場合は、共有キャッシュを無効にすれば、キャッシュの整合性の問題を回避できます。すべてのオブジェクトの共有キャッシュを無効にするには、persistence.xmlファイルの<shared-cache-mode>要素を使用します。次に例を示します。

<shared-cache-mode>NONE</shared-cache-mode>

共有キャッシュを選択的に有効または無効にするには、エンティティを定義する際に、@Cache注釈のshared属性を使用します。次に例を示します。

...
@Entity
@Cache(shared=false)
public class Employee {
...
}

5.2.1.2 キャッシュのリフレッシュ

アプリケーションが現在のデータの使用を確実にするために、キャッシュをリフレッシュするとデータベースからキャッシュがリロードされます。ここでは、キャッシュの様々なリフレッシュ方法について説明します。

@cache注釈には、すべての問合せを強制的にデータベースに向かわせてキャッシュをリフレッシュするalwaysRefresh属性とrefreshOnlyIfNewer属性が用意されています。

...
@Entity
@Cache(
alwaysRefresh=true,
refreshOnlyIfNewer=true)
public class Employee {
...
}

org.eclipse.persistence.jpa.JpaCacheインタフェースには、キャッシュが最新でない場合に失効オブジェクトを削除するメソッドがいくつか含まれています。

- evictAllメソッドは、キャッシュ内のすべてのオブジェクトを無効にします。次に例を示します。

em.getEntityManagerFactory().getCache().evictAll();

- 特定のクラスを無効にするには、evictメソッドを使用します。

em.getEntityManagerFactory().getCache().evict(MyClass);

- clearメソッドもキャッシュをリフレッシュしますが、キャッシュをクリアすると、キャッシュされているオブジェクトが使用中の場合に、オブジェクトIDの問題が発生する可能性があります。このメソッドは、キャッシュに保持されているオブジェクトに対する参照がアプリケーションにもう存在しないことがわかっている場合にのみ使用してください。

これまでに説明したメソッドは受動的で、次回にキャッシュにアクセスしたときにのみオブジェクトがリフレッシュされます。オブジェクトを能動的にリフレッシュするには、EntityManager.refreshメソッドを使用します。このメソッドは1回に1つのオブジェクトをリフレッシュします。

次のAPIでも、キャッシュがリフレッシュされます。

- Session.refreshObject

- DatabaseSessionおよびUnitOfWork: refreshAndLockObjectメソッド

- ObjectLevelReadQuery: refreshIdentityMapResultおよびrefreshRemoteIdentityMapResultメソッド

ClassDescriptorクラスにも、キャッシュをリフレッシュするメソッドが用意されています。

- setShouldAlwaysRefreshCache

- setShouldAlwaysRefreshCacheOnRemote

- setShouldDisableCacheHits

- setShouldDisableCacheHitsOnRemote

- setShouldOnlyRefreshCacheIfNewerVersion

これらのメソッドはディスクリプタ修正メソッド内で使用します。次に例を示します。

public void addToDescriptor(ClassDescriptor descriptor) {
descriptor.setShouldRefreshCacheOnRemote(true);
descriptor.setShouldDisableCacheHitsOnRemote(true);
}

最後に、問合せヒントは、キャッシュをリフレッシュする問合せをトリガーします。次に例を示します。

Query query = em.createQuery("Select e from Employee e");
query.setHint("javax.persistence.cache.storeMode", "REFRESH");

5.2.1.3 キャッシュ有効期限の設定

キャッシュ有効期限を設定した場合、指定時間が経過すると、キャッシュされたオブジェクト・インスタンスが無効になります。そのオブジェクトを使用しようとすると、最新バージョンのオブジェクトがデータ・ソースからリロードされます。有効期限は、アプリケーションが確実に最新データを使用するようにするのに便利です。ここでは、有効期限の様々な設定方法について説明します。

@cache注釈には、特定の時間が経つとキャッシュ・インスタンスを削除するexpiryおよびexpiryTimeOfDay属性が用意されています。expiry属性は、ミリ秒単位で入力します。値を指定しない場合のデフォルト値は-1で、有効期限が無効になっていることを示します。expiryTimeOfDay属性は、org.eclipse.persistence.annotations.TimeOfDayインタフェースのインスタンスです。次の例では、5分後にオブジェクトが期限切れになるように設定しています。

...
@Entity
@Cache(expiry=300000)
public class Employee {
...
}

ディスクリプタ・レベルで、ClassDescriptor.setCacheInvalidationPolicyメソッドを使用して、CacheInvalidationPolicyインスタンスを設定します。次の無効化ポリシーを使用できます。

- DailyCacheInvalidationPolicy: 毎日指定の時間に無効フラグがオブジェクトに自動的に設定されます。

- NoExpiryCacheInvalidationPolicy: IdentityMapAccessor.invalidateObjectメソッドを明示的にコールした場合にのみ、オブジェクトに無効フラグを設定できます。

- TimeToLiveCacheInvalidationPolicy: オブジェクトの読取りから指定時間が経過した後に、無効フラグがオブジェクトに自動的に設定されます。

5.2.1.4 オプティミスティック・ロックの設定

オプティミスティック・ロックでは、あるユーザーが別のユーザーの作業を上書きできないようにします。ロックは、複数のサーバーまたは複数のアプリケーションが同じデータにアクセスする場合に重要で、単一サーバーとマルチサーバーの両方の環境に関係があります。マルチサーバー環境においては、アプリケーションがキャッシュ・リフレッシュやキャッシュ・コーディネーションを使用している場合であっても、やはりロックは必要です。ここでは、オプティミスティック・ロックの様々な設定方法について説明します。

@OptimisticLocking注釈には、エンティティを更新または削除する際に使用するオプティミスティック・ロックのタイプを指定します。オプティミスティック・ロックは、@Entityまたは@MappedSuperclass注釈でサポートされています。次の属性を使用できます。

- ALL_COLUMNS: このポリシーでは、更新または削除を実行する際に、WHERE句の表のすべてのフィールドが比較されます。

- CHANGED_COLUMNS: このポリシーでは、更新を実行する際に、WHERE句の変更されたフィールドのみが比較されます。削除操作では、主キーのみが比較されます。

- SELECTED_COLUMNS: このポリシーでは、更新または削除を実行する際に、WHERE句の選択されたフィールドが比較されます。指定されたフィールドはマップされている必要があり、主キーではない必要があります。

- VERSION_COLUMN: (デフォルト)このポリシーでは、単一のバージョン番号をオプティミスティック・ロックに使用できます。バージョン・フィールドはマップされている必要があり、主キーではない必要があります。親オブジェクトが私有する子オブジェクトのバージョン・フィールドが変更された場合に、その親オブジェクトのバージョン・フィールドが強制的に自動更新されるようにするには、cascadedメソッドをtrueに設定します。デフォルトでは、このメソッドはfalseに設定されます。

ディスクリプタ・レベルで、ClassDescriptor.setOptimisticLockingPolicyメソッドを使用してオプティミスティック・ロックを構成し、オプティミスティックなFieldsLockingPolicyインスタンスを設定します。注釈と同様に、次のポリシーが含まれています。

- AllFieldsLockingPolicy: このポリシーでは、更新または削除を実行する際に、WHERE句の表のすべてのフィールドが比較されます。

- ChangedFieldsLockingPolicy: このポリシーでは、更新を実行する際に、WHERE句の変更されたフィールドのみが比較されます。削除操作では、主キーのみが比較されます。

- SelectedFieldsLockingPolicy: このポリシーでは、更新または削除を実行する際に、WHERE句の選択されたフィールドが比較されます。指定されたフィールドはマップされている必要があり、主キーではない必要があります。

- VersionLockingPolicy: このポリシーを使用すれば、単一のバージョン番号をオプティミスティック・ロックに使用できます。親オブジェクトが私有する子オブジェクトのバージョン・フィールドが変更された場合に、その親オブジェクトのバージョン・フィールドが強制的に自動更新されるようにするには、VersionLockingPolicy.setIsCascadedメソッドをtrueに設定します。

- TimestampLockingPolicy: このポリシーを使用すれば、単一のバージョン・タイムスタンプをオプティミスティック・ロックに使用できます。

5.2.1.5 キャッシュ・コーディネーションの使用

キャッシュ・コーディネーションは、分散セッション間で変更を同期します。すべてのアプリケーションに対してデータの整合性を維持するのが困難なアプリケーション・サーバー・クラスタでは、キャッシュ・コーディネーションが最も有効です。さらに、1つの環境内のサーバー数が増えるにつれて、キャッシュの整合性を保つのはますます難しくなります。

キャッシュ・コーディネーションは、クラスタ内のセッション(ServerSessionまたは永続性ユニット)間のトランザクション・オブジェクトの変更通知をブロードキャストすることにより動作します。アプリケーションが読取り中心で、複数の分散セッションで運用される同一アプリケーションによって変更が実行される場合に、キャッシュ・コーディネーションは最も有効です。

キャッシュ・コーディネーションを使用すると、失効データが大幅に減少しますが、失効データが発生する可能性を完全になくすことはできません。さらに、キャッシュ・コーディネーションにより、分散アーキテクチャで発生するオプティミスティック・ロック例外の数は減少し、アプリケーションで失敗するトランザクションや繰り返されるトランザクションの数も減少します。とはいえ、キャッシュ・コーディネーションを行っても、効果的なロック・ポリシーが不要になることはありません。現在のデータを確実に使用するには、オプティミスティック・ロックまたはペシミスティック・ロックとともにキャッシュ・コーディネーションを使用しますが、オプティミスティック・ロックの使用の方をお薦めします。

キャッシュ・コーディネーションはRMIおよびJMS上でサポートされており、persistence.xmlファイルの永続性プロパティを使用して宣言的に構成することも、キャッシュ・コーディネーションのAPIを使用することもできます。永続性プロパティに一致するシステム・プロパティも使用できます。

キャッシュ・コーディネーションの詳細は、次を参照してください。

http://wiki.eclipse.org/Introduction_to_Cache_%28ELUG%29#Cache_Coordination_2

永続性プロパティを使用したJMSキャッシュ・コーディネーションの構成

次の例は、persistence.xmlファイルでキャッシュ・コーディネーションを構成する方法を示しており、通知のブロードキャストにJMSを使用しています。JMSでは、プロトコルに加えて、JMSトピック、JNDI名およびトピック接続ファクトリのJNDI名を指定します。JMSトピックでは、JTAを有効にせず、永続性メッセージを指定しないでください。

<property name="eclipselink.cache.coordination.protocol" value="jms" />
<property name="eclipselink.cache.coordination.jms.topic"
value="jms/EmployeeTopic" />
<property name="eclipselink.cache.coordination.jms.factory"
value="jms/EmployeeTopicConnectionFactory" />

クラスタで実行されるアプリケーションでは、リソースを探して使用にはトピックで十分なので、URLは通常不要です。クラスタ外部で実行されるアプリケーションの場合は、URLが必要です。WebLogicサーバー・クラスタのURLの例を次に示します。

<property name="eclipselink.cache.coordination.jms.host"
value="t3://myserver:7001/" />

必要な場合は、サーバーにアクセスするために必要なユーザー名とパスワードも設定できます。次に例を示します。

<property name="eclipselink.cache.coordination.jndi.user" value="user" />
<property name="eclipselink.cache.coordination.jndi.password" value="password" />

永続性プロパティを使用したRMIキャッシュ・コーディネーションの構成

次の例は、persistence.xmlファイルでキャッシュ・コーディネーションを構成する方法を示しており、通知のブロードキャストにRMIを使用しています。

<property name="eclipselink.cache.coordination.protocol" value="rmi" />

クラスタで実行されるアプリケーションでは、JNDIがレプリケートされて各サーバーが相互のリスナーを参照できるので、URLは通常不要です。アプリケーションがクラスタ外部で実行される場合またはJNDIがレプリケートされない場合は、各サーバーでURLを指定する必要があります。これは、persistence.xmlファイルを使用して行えますが、各サーバーに対して別のpersistence.xmlファイル(たとえばJARまたはEAR)が必要になり、通常は望ましくありません。2番目のオプションとしては、キャッシュ・コーディネーションAPIを使用して、URLをプログラムで設定します。「キャッシュ・コーディネーションAPIを使用したキャッシュ・コーディネーションの構成」を参照してください。最後のオプションは、各アプリケーション・サーバーのシステム・プロパティとしてURLを設定する方法です。次の例では、システム・プロパティを使用してWebLogicサーバー・クラスタのURLを設定しています。

-Declipselink.cache.coordination.jms.host=t3://myserver:7001/

必要な場合は、サーバーにアクセスするために必要なユーザー名とパスワードも、次のように設定できます。

<property name="eclipselink.cache.coordination.jndi.user" value="user" /><property name="eclipselink.cache.coordination.jndi.password" value="password" />

RMIキャッシュ・コーディネーションでは、非同期または同期のブロードキャストを使用できます。デフォルトでは非同期になります。同期ブロードキャストでは、リクエストが返される前に、すべてのサーバーが確実に更新されます。次の例では、同期ブロードキャストを構成しています。

<property name="eclipselink.cache.coordination.propagate-asynchronously"
value="false" />

同じサーバーまたはネットワーク上の複数のアプリケーションがキャッシュ・コーディネーションを使用する場合は、アプリケーションごとに別のチャネルを使用できます。次に例を示します。

<property name="eclipselink.cache.coordination.channel" value="EmployeeChannel" />

最後に、必要に応じて、サーバーが相互に検索できるようにするデフォルトのRMIマルチキャスト・ソケット・アドレスを変更します。次の例では、マルチキャスト設定を明示的に構成しています。

<property name="eclipselink.cache.coordination.rmi.announcement-delay"
value="1000" />
<property name="eclipselink.cache.coordination.rmi.multicast-group"
value="239.192.0.0" />
<property name="eclipselink.cache.coordination.rmi.multicast-group.port"
value="3121" />
<property name="eclipselink.cache.coordination.packet-time-to-live" value="2" />

キャッシュ・コーディネーションAPIを使用したキャッシュ・コーディネーションの構成

CommandManagerインタフェースを使用して、セッションのキャッシュ・コーディネーションをプログラムで構成します。次の例では、RMIキャッシュ構成を構成しています。

Session.getCommandManager().setShouldPropagateAsynchronously(boolean)

Session.getCommandManager().getDiscoveryManager().
setAnnouncementDelay()
setMulticastGroupAddress()
setMulticastPort()
setPacketTimeToLive()

Session.getCommandManager().getTransportManager().
setEncryptedPassword()
setInitialContextFactoryName()
setLocalContextProperties(Hashtable)
setNamingServiceType() //passing in one of:
TransportManager.JNDI_NAMING_SERVICE
TransportManager.REGISTRY_NAMING_SERVICE
setPassword()
setRemoteContextProperties(Hashtable)
setShouldRemoveConnectionOnError()
setUserName()

キャッシュ同期の設定

キャッシュ同期では、オブジェクトの変更がセッション・メンバー間にブロードキャストされる方法を決定します。次の同期モードを使用できます。

- SEND_OBJECT_CHANGES: (デフォルト)このオプションでは、変更に関するデータを含む、変更されたオブジェクトのリストが送信されます。このデータは、受信キャッシュにマージされます。

- INVALIDATE_CHANGED_OBJECTS: このオプションでは、変更されたオブジェクトのIDリストが送信されます。受信キャッシュでは、データを変更するのではなく、オブジェクトが無効にされます。

- SEND_NEW_OBJECTS_WITH_CHANGES: このオプションは、トランザクションで新規作成されたオブジェクトも含まれる点以外はSEND_OBJECT_CHANGESオプションと同じです。

- NONE: このオプションでは、キャッシュ・コーディネーションは行われません。

@cache注釈のcoordinationType属性は、同期モードを指定するために使用します。次に例を示します。

...
@Entity
@Cache(CacheCoordinationType.SEND_NEW_OBJECTS_CHANGES)
public class Employee {
...
}

ObjectChangeSet.setCacheSynchronizationTypeメソッドを使用して、同期モードを設定することもできます。次に例を示します。

setCacheSynchronizationType() // passing in one of:
ClassDescriptor.DO_NOT_SEND_CHANGES
ClassDescriptor.INVALIDATE_CHANGED_OBJECTS
ClassDescriptor.SEND_NEW_OBJECTS_WITH_CHANGES
ClassDescriptor.SEND_OBJECT_CHANGES

5.2.2 タスク2: TopLinkの有効化の確認

TopLink JARファイルが、TopLinkアプリケーションがデプロイされているクラスタの各アプリケーション・サーバーのクラスパスに含まれていることを確認して、TopLinkを永続性プロバイダとして構成します。WebLogicサーバーおよびGlassFishでTopLinkを構成する詳細な手順は、第2章「WebLogic ServerでのTopLinkの使用」および第3章「GlassFish ServerでのTopLinkの使用」を参照してください。

5.2.3 タスク3: すべてのアプリケーション・サーバーがクラスタ内にあることの確認

TopLinkアプリケーションをホストする各アプリケーション・サーバーを含むアプリケーション・サーバー・クラスタを構成します。

- WLSクラスタリングの詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverクラスタの使用』を参照してください。

- GlassFishのクラスタリングについては、次を参照してください。
http://download.oracle.com/docs/cd/E18930_01/html/821-2426/index.html

5.3 その他の参照資料

次の参照資料を使用できます。

- 5.3.1項「コード・サンプル」

- 5.3.2項「関連JavaDoc」

5.3.1 コード・サンプル

http://wiki.eclipse.org/EclipseLink/Examples/JPA/CacheCoordination

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

5.3.2 関連JavaDoc

詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』の次のAPIを参照してください。

- org.eclipse.persistence.annotations.OptimisticLocking

- org.eclipse.persistence.annotations.Cache

- org.eclipse.persistence.descriptors.ClassDescriptor

- org.eclipse.persistence.sessions.coordination

6 サービスとしてのソフトウェアの提供

この章では、Software as a Service (SaaS)環境で動作する共有TopLinkアプリケーションを作成する手順を説明します。

この章では、次の項目について説明します。

- 6.1項「SaaSとしてのOracle TopLinkの理解」

- 6.2項「JPAエンティティの拡張可能化」

- 6.3項「JAXB Beanの拡張可能化」

- 6.4項「単一表マルチテナントの使用」

- 6.5項「外部メタデータ・ソースの使用」

6.1 SaaSとしてのOracle TopLinkの理解

SaaS用のOracleプラットフォームには、Oracle Fusion Middlewareの一部であるTopLinkが含まれます。これにより、SaaSアプリケーションのビルド、デプロイおよび管理が可能になっています。TopLinkでは、クラウド対応のアプリケーションおよびサービスで永続性を管理できます。高いパフォーマンスとスケーラビリティを維持しながら、マルチテナントおよび拡張性に対処する、より柔軟なSaaSソリューションを開発するには、これらのアプリケーションの永続性レイヤーが重要なコンポーネントになります。

TopLinkでは、拡張性、マルチテナント、および外部メタデータ・ソースの使用をサポートすることにより、サービスとしてのソフトウェアの提供をサポートしており、次の項に、その詳細が説明されています。

- 6.2項「JPAエンティティの拡張可能化」

- 6.3項「JAXB Beanの拡張可能化」

- 6.4項「単一表マルチテナントの使用」

- 6.5項「外部メタデータ・ソースの使用」

6.2 JPAエンティティの拡張可能化

@VirtualAccessMethods注釈を使用して、エンティティが拡張可能であることを指定します。拡張可能なエンティティで仮想プロパティを使用すれば、エンティティの外部でマッピングを指定できます。これにより、エンティティのソース・ファイルの変更およびエンティティの永続性ユニットの再デプロイをしなくても、マッピングを変更できるようになります。

拡張可能なエンティティは、複数のクライアント(テナント)が共有の汎用アプリケーションを使用できるマルチテナント(またはSaaS)環境で使用するのに役立ちます。テナントは、自分のデータにプライベートにアクセスでき、他のテナントと共有するデータにもアクセスできます。

拡張可能なエンティティを使用すれば、次のことを行えます。

- 一部のマッピングがすべてのユーザーに共通で、一部のマッピングはユーザー固有であるようなアプリケーションを作成できます。

- 顧客に提供された後のアプリケーションにマッピングを追加できます(デプロイメント後でも可能)。

- マッピング変更後も、同じEntityManagerFactoryを使用してデータを操作できます。

- アプリケーションで使用されるメタデータのソースを追加提供できます。

6.2.1 主なタスク

拡張可能なJPAエンティティを作成およびサポートするには:

- タスク1: エンティティの構成

- タスク2: スキーマの設計

- タスク3: 追加マッピングの提供

- タスク4: 永続性プロパティおよびデータ・リポジトリの構成

6.2.1.1 タスク1: エンティティの構成

エンティティの構成では、@VirtualAccessMethodsによるエンティティ・クラスの注釈指定、プロパティ値に対するgetおよびsetメソッドの追加、および拡張された属性と値をストアするデータ構造の追加をします。

6.2.1.1.1 @VirtualAccessMethodsによるエンティティ・クラスの注釈指定

@VirtualAccessMethodsでエンティティに注釈を付けて、エンティティが拡張可能であることを指定し、仮想プロパティを定義します。

表6-1は、@VirtualAccessMethods注釈で使用可能な属性を説明しています。

表6-1 @VirtualAccessMethods注釈の属性

属性

説明

get

仮想プロパティに使用するgetterメソッドの名前。このメソッドは、1つのjava.lang.Stringパラメータを受け取ってjava.lang.Objectを返す必要があります。

デフォルト: get

必須かどうか:いいえ

set

仮想プロパティに使用するsetterメソッドの名前。このメソッドは、java.lang.Stringおよびjava.lang.Objectパラメータを受け取ってjava.lang.Objectパラメータを返す必要があります。

デフォルト: set

必須かどうか:いいえ

6.2.1.1.2 エンティティに対するgetおよびsetメソッドの追加

エンティティに対して、get(String)およびset(String, Object)メソッドを追加します。get()メソッドは、プロパティ名によって値を返し、set()メソッドはプロパティ名によって値をストアします。これらのメソッドのデフォルト名は、getおよびsetで、@VirtualAccessMethods注釈でオーバーライドできます。

EclipseLinkでは、ウィービングが有効な場合に、これらのメソッドがウィービングされて、遅延ロード、変更追跡、フェッチ・グループおよび内部最適化がサポートされます。get(String)およびset(String, Object)シグネチャを使用する必要があります。そうしないと、ウィービングは動作しません。

注意:

OneToOneマッピングで仮想アクセス・メソッドを使用する場合、ウィービングはサポートされません。使用すると、例外がスローされます。

6.2.1.1.3 データ構造の追加

拡張された属性と値、つまり仮想マッピングをストアするデータ構造を追加します。その後、これらをデータベースにマップできます。6.2.1.3項「タスク3: 追加マッピングの提供」を参照してください。

仮想マッピングは(例6-1に示されているような)Mapにストアするのが一般的ですが、他の方式を使用することもできます。たとえば、ディレクトリ・システムに仮想マッピングをストアすることもできます。

フィールドベースのアクセスを使用する際には、@Transientでデータ構造に注釈を付けて、この構造を別のマッピングに使用できないようにします。プロパティベースのアクセスを使用する場合、@Transientは不要です。

例6-1に、プロパティ・アクセスを使用するエンティティ・クラスを示します。

例6-1 プロパティ・アクセスを使用するエンティティ・クラス

@Entity
@VirtualAccessMethods
public class Customer{

@Id
private int id;
...

@Transient
private Map<String, Object> extensions;

public <T> T get(String name) {
return (T) extentions.get(name);
}

public Object set(String name, Object value) {
return extensions.put(name, value);
}

6.2.1.1.4 XMLの使用

@VirtualAccessMethodsを使用する方法に加えて、代替方法として、<access>および<access-methods>要素を、次のように使用することもできます。

<access>VIRTUAL</access>
<access-methods set-method="get" get-method="set"/>

6.2.1.2 タスク2: スキーマの設計

フレキシブルなマッピング・データを保存するために、余分な列があるデータベース表を用意します。たとえば、次のCustomer表には、事前定義された2つの表、IDおびNAMEがあり、3つのフレキシブル列、FLEX_COL1、FLEX_COL2、FLEX_COL3があります。

- CUSTOMER

- INTEGER ID

- VARCHAR NAME

- VARCHAR FLEX_COL1

- VARCHAR FLEX_COL2

- VARCHAR FLEX_COL3

次に、「タスク3: 追加マッピングの提供」に説明されているように、拡張された属性を永続化するために、どのフレキシブル列を使用するかを指定できます。

6.2.1.3 タスク3: 追加マッピングの提供

追加マッピングを提供するには、columnおよびaccess-methods属性が指定されたマッピングをeclipselink-orm.xmlファイルに追加します。次に例を示します。

<basic name="idNumber" attribute-type="String">
<column name="FLEX_COL1"/>
<access-methods get-method="get" set-method="set"/>
</basic>

6.2.1.4 タスク4: 永続性プロパティおよびデータ・リポジトリの構成

永続性ユニット・プロパティを構成して、アプリケーションがeclipselink-orm.xmlファイルからフレキシブル・マッピングを取得する必要があることを示します。次の項に説明されているように、persistence.xmlを使用するか、EntityManagerFactoryにプロパティを設定して、永続性ユニット・プロパティを設定できます。

外部マッピングの詳細は、EclipseLinkドキュメントの『External Mappings』を参照してください。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/External_Mappings

6.2.1.4.1 persistence.xmlの構成

デフォルトのeclipselink-orm.xmlファイルを使用するには、persistence.xmlファイルでeclipselink.metadata-sourceプロパティを使用します。指定した場所にある別のファイルを使用するには、eclipselink.metadata-source.xml.urlプロパティを使用します。次に例を示します。

<property name="eclipselink.metadata-source" value="XML"/>
<property name="eclipselink.metadata-source.xml.url" value="foo://bar"/>

6.2.1.4.2 EntityManagerFactoryおよびメタデータ・リポジトリの構成

拡張機能は、ブートストラップ時にメタデータ・リポジトリにアクセスして追加されます。メタデータ・リポジトリには、そこに保持されているメタデータを取得するメソッドを提供するクラスを介してアクセスします。現在のリリースには、XMLリポジトリをサポートするメタデータ・リポジトリの実装が含まれています。

メタデータ・リポジトリに対して使用するクラスおよび構成情報を永続性ユニット・プロパティに指定します。エンティティ・マネージャ・ファクトリでは、メタデータ・リポジトリの追加マッピング情報が、ブートストラップに使用されるメタデータに統合されます。

独自のクラスの実装を用意して、メタデータ・リポジトリにアクセスできます。各メタデータ・リポジトリ・アクセス・クラスには、リポジトリに接続するために使用するプロパティのセットを個別に指定する必要があります。

次のクラスのどちらかをサブクラスにできます。

- org.eclipse.persistence.internal.jpa.extensions.MetadataRepository

- org.eclipse.persistence.internal.jpa.extensions.XMLMetadataRepository

次の例では、com.fooで始まるプロパティが、開発者によって定義されています。

<property name="eclipselink.metadata-source" value="com.foo.MetadataRepository"/>
<property name="com.foo.MetadataRepository.location" value="foo://bar"/>
<property name="com.foo.MetadataRepository.extra-data" value="foo-bar"/>

6.2.1.4.3 メタデータ・リポジトリのリフレッシュ

メタデータを変更して、新しいメタデータに基づくEntityManagerが必要な場合は、refreshMetadata()をEntityManagerFactoryで呼び出して、データをリフレッシュする必要があります。次のEntityManagerは、新しいメタデータに基づいたものになります。

refreshMetadataメソッドは、プロパティのMapを受け取って、プロパティのそのマップを使用して、metadata-sourceに以前に定義されていたプロパティをオーバーライドできます。

6.2.2 コード例

例6-2は、次のことを示しています。

- 非拡張フィールドには、フィールド・アクセスが使用されています。

- 拡張フィールドには、デフォルト(get(String)およびset(String, Object))を使用した仮想アクセスが使用されています。

- get(String)およびset(String, Object)メソッドは、マッピングで使用されていなくても、@VirtualAccessMethodsが指定されているので、ウィービングされます。

- 拡張機能は、@Transientを指定して、移植可能な方法でマッピングされています。

例6-2 デフォルトのgetおよびsetメソッド名を使用した仮想アクセス

@Entity
@VirtualAccessMethods
public class Address {

@Id
private int id;

@Transient
private Map<String, Object> extensions;

public int getId(){
return id;
}

public <T> T get(String name) {
return (T) extentions.get(name);
}

public Object set(String name, Object value) {
return extensions.put(name, value);
}

...

例6-3は、次のことを示しています。

- 非拡張フィールドには、フィールド・アクセスが使用されています。

- getおよびsetに使用されるメソッドを@VirtualAccessMethods注釈でオーバーライドしています。

- get(String)およびset(String, Object)メソッドは、マッピングで使用されていなくても、@VirtualAccessMethodsが指定されているので、ウィービングされます。

- 拡張機能は、@Transientを指定して、移植可能な方法でマッピングされています。

- get()およびset()メソッドのどちらを使用するかを、拡張マッピングのXMLで示しています。

例6-3 GetおよびSetメソッドのオーバーライド

@Entity
@VirtualAccessMethods(get="getExtension", set="setExtension")
public class Address {

@Id
private int id;

@Transient
private Map<String, Object> extensions;

public int getId(){
return id;
}

public <T> T getExtension(String name) {
return (T) extensions.get(name);
}

public Object setExtension(String name, Object value) {
return extensions.put(name, value);
}

...

<basic name="name" attribute-type="String">
<column name="FLEX_1"/>
<access-methods get-method="getExtension" set-method="setExtension"/>
</basic>

例6-4は、次のことを示しています。

- 非拡張フィールドには、プロパティ・アクセスが使用されています。

- 拡張フィールドには、デフォルト(get(String)およびset(String, Object))を使用した仮想アクセスが使用されています。

- 拡張機能は移植可能な方法でマッピングされています。プロパティ・アクセスが使用されるので、@Transientは不要です。

- get(String)およびset(String, Object)メソッドは、マッピングで使用されていなくても、@VirtualAccessMethodsが指定されているので、ウィービングされます。

例6-4 プロパティ・アクセスの使用

@Entity
@VirtualAccessMethods
public class Address {

private int id;

private Map<String, Object> extensions;

@Id
public int getId(){
return id;
}

public <T> T get(String name) {
return (T) extensions.get(name);
}

public Object set(String name, Object value) {
return extensions.put(name, value);
}

...

6.3 JAXB Beanの拡張可能化

@XmlVirtualAccessMethods注釈を使用して、JAXB Beanが拡張可能であることを指定します。拡張可能なBeanで仮想プロパティを使用すれば、Beanの外部でマッピングを指定できます。これにより、Beanのソース・ファイルの変更およびBeanの永続性ユニットの再デプロイをしなくても、マッピングを変更できるようになります。

マルチテナント(またはSaaS)アーキテクチャでは、サーバーで1つのアプリケーションが動作して、複数のクライアント組織(テナント)にサービスを提供します。優れたマルチテナント・アプリケーションでは、テナントごとのカスタマイズが可能です。これらのカスタマイズがデータに対して行われる場合は、バインディング・レイヤーでカスタマイズを処理するのが難しい場合があります。JAXBは、実際のフィールドおよびプロパティがあるドメイン・モデルを操作するように設計されています。EclipseLink Object-XML 2.3 (MOXyとも呼ばれます)には、このユースケースを容易に処理できる、仮想プロパティの概念が導入されています。仮想プロパティはObject-XMLメタデータ・ファイルによって定義されているので、ソースを変更しなくてもクラスを拡張できます。

この項の内容は、次のとおりです。

- 6.3.1項「主な手順」

- 6.3.2項「コード例」

6.3.1 主な手順

拡張可能なJAXB Beanを作成およびサポートするには:

- タスク1: Beanの構成

- タスク2: 追加マッピングの提供

6.3.1.1 タスク1: Beanの構成

Beanの構成では、@XmlVirtualAccessMethodsによるBeanクラスの注釈指定、プロパティ値に対するgetおよびsetメソッドの追加、および拡張された属性と値をストアするデータ構造の追加をします。

6.3.1.1.1 @Xml VirtualAccessMethodsによるBeanクラスの注釈指定

@XmlVirtualAccessMethodsでBeanに注釈を付けて、Beanが拡張可能であることを指定し、仮想プロパティを定義します。

表6-2は、@XmlVirtualAccessMethods注釈で使用可能な属性を説明しています。

表6-2 @XmlVirtualAccessMethods注釈の属性

属性

説明

get

仮想プロパティに使用するgetterメソッドの名前。このメソッドは、1つのjava.lang.Stringパラメータを受け取ってjava.lang.Objectを返す必要があります。

デフォルト: get

必須かどうか:いいえ

set

仮想プロパティに使用するsetterメソッドの名前。このメソッドは、java.lang.Stringおよびjava.lang.Objectパラメータを受け取ってjava.lang.Objectパラメータを返す必要があります。

デフォルト: set

必須かどうか:いいえ

6.3.1.1.2 Beanに対するgetおよびsetメソッドの追加

Beanに対して、get(String)およびset(String, Object)メソッドを追加します。get()メソッドは、プロパティ名によって値を返し、set()メソッドはプロパティ名によって値をストアします。これらのメソッドのデフォルト名は、getおよびsetで、@XmlVirtualAccessMethods注釈でオーバーライドできます。

EclipseLinkでは、ウィービングが有効な場合に、これらのメソッドがウィービングされて、遅延ロード、変更追跡、フェッチ・グループおよび内部最適化がサポートされます。

6.3.1.1.3 データ構造の追加

拡張された属性と値、つまり仮想マッピングをストアするデータ構造を追加します。その後、これらをデータベースにマップできます。「タスク2: 追加マッピングの提供」を参照してください。

仮想マッピングはMapにストアするのが一般的ですが、他の方式を使用することもできます。たとえば、ディレクトリ・システムに仮想マッピングをストアすることもできます。

フィールドベースのアクセスを使用する際には、@XmlTransientでデータ構造に注釈を付けて、この構造を別のマッピングに使用できないようにします。プロパティベースのアクセスを使用する場合、@XmlTransientは不要です。

6.3.1.1.4 XMLの使用

@XmlVirtualAccessMethodsを使用する方法に加えて、代替方法として、<access>および<access-methods>要素を、次のように使用することもできます。

<access>VIRTUAL</access>
<access-methods set-method="get" get-method="set"/>

getおよびsetを使用する仮想アクセス・メソッドを有効にするXML:

<xml-virtual-access-methods/>

setではなくputを使用する仮想アクセス・メソッドを有効にするXML(デフォルト):

<xml-virtual-access-methods set-method="put"/>

getではなくretrieveを使用する仮想アクセス・メソッドを有効にするXML(デフォルト):

<xml-virtual-access-methods get-method="retrieve"/>

getとsetではなくretrieveとputを使用する仮想アクセス・メソッドを有効にするXML(デフォルト):

<xml-virtual-access-methods get-method="retrieve" set-method="put"/>

6.3.1.2 タスク2: 追加マッピングの提供

追加マッピングを提供するには、マッピングをeclipselink-oxm.xmlファイルに追加します。次に例を示します。

<xml-element java-attribute="idNumber"/>

6.3.2 コード例

この項の例は、拡張可能なJAXB Beanを使用する方法を示します。この例では、他のクラスが拡張できるベース・クラスを最初に作成します。この場合、拡張可能なクラスは、CustomersおよびPhoneNumbers用です。マッピング・ファイルは2つの個別のテナントに対して作成されています。両方のテナントはいくつかの実際のプロパティを共有していますが、それぞれの要件に固有の仮想プロパティを定義します。

6.3.2.1 基本設定

例6-5は、他の拡張可能なクラスが拡張できるベース・クラスExtensibleBaseを示しています。この例では、@XmlTransient注釈を使用することにより、ExtensibleBaseが継承関係としてマップされないようにしています。モデル内で、すべてのテナントに共通な部分は、実際のプロパティで表されます。テナントごとの拡張機能は、仮想プロパティとして表されます。

例6-5 拡張可能なクラスのベース・クラス

package examples.virtual;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.annotation.XmlTransient;

import org.eclipse.persistence.oxm.annotations.XmlVirtualAccessMethods;

@XmlTransient
@XmlVirtualAccessMethods(setMethod="put")
public class ExtensibleBase {

private Map<String, Object> extensions = new HashMap<String, Object>();

public <T> T get(String property) {
return (T) extensions.get(property);
}

public void put(String property, Object value) {
extensions.put(property, value);
}
}

例6-6に、Customerクラスの定義を示します。Customerクラスは、@XmlVirtualAccessMethods注釈が付けられたドメイン・クラスから継承するので拡張可能です。

例6-6 拡張可能なCustomerクラス

package examples.virtual;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer extends ExtensibleBase {

private String firstName;
private String lastName;
private Address billingAddress;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public Address getBillingAddress() {
return billingAddress;
}

public void setBillingAddress(Address billingAddress) {
this.billingAddress = billingAddress;
}

}

例6-7に、Addressクラスを示します。モデル内のすべてのクラスを拡張可能にする必要はありません。この例のAddressクラスには、仮想プロパティはありません。

例6-7 拡張可能ではないAddressクラス

package examples.virtual;

public class Address {

private String street;

public String getStreet() {
return street;
}

public void setStreet(String street) {
this.street = street;
}

}

例6-8に、PhoneNumberクラスを示します。Customerと同様に、PhoneNumberは拡張可能なクラスになります。

例6-8 拡張可能なPhoneNumberクラス

package examples.virtual;

import javax.xml.bind.annotation.XmlValue;

public class PhoneNumber extends ExtensibleBase {

private String number;

@XmlValue
public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}

}

6.3.2.2 テナントの定義

この項の例では、2つの個別のテナントが定義されています。両方のテナントはいくつかの実際のプロパティを共有していますが、仮想プロパティが指定されているので、対応するXML表現はまったく異なるものにできます。

テナント1

最初のテナントは、オンライン・スポーツ用品店で、次のようにモデルを拡張する必要があります。

- 顧客ID

- 顧客のミドル・ネーム

- 配送先住所

- 連絡先電話番号のコレクション

- 電話番号のタイプ(自宅、勤務先、または携帯など)

仮想プロパティのメタデータは、Object-XMLのXMLマッピング・ファイルを介して指定します。仮想プロパティは、実際のプロパティと同様の方法でマップされます。タイプ(リフレクションでは特定できないため)、およびコレクション・プロパティの場合はコンテナ・タイプなど、追加情報がいくらか必要です。次に定義されているCustomerの仮想プロパティは、middleName、shippingAddressおよびphoneNumbersです。PhoneNumberの仮想プロパティはtypeプロパティです。

例6-9に、binding-tenant1.xmlマッピング・ファイルを示します。

例6-9 テナント1の仮想プロパティの定義

<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="examples.virtual">
<java-types>
<java-type name="Customer">
<xml-type prop-order="firstName middleName lastName billingAddress shippingAddress phoneNumbers"/>
<java-attributes>
<xml-attribute
java-attribute="id"
type="java.lang.Integer"/>
<xml-element
java-attribute="middleName"
type="java.lang.String"/>
<xml-element
java-attribute="shippingAddress"
type="examples.virtual.Address"/>
<xml-element
java-attribute="phoneNumbers"
name="phoneNumber"
type="examples.virtual.PhoneNumber"
container-type="java.util.List"/>
</java-attributes>
</java-type>
<java-type name="PhoneNumber">
<java-attributes>
<xml-attribute
java-attribute="type"
type="java.lang.String"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>

getおよびsetメソッドは、実際のプロパティを操作するためにドメイン・モデルで使用し、@XmlVirtualAccessMethods注釈に定義されているアクセッサは、仮想プロパティを操作するために使用します。通常のJAXBメカニズムは、操作のマーシャルおよびアンマーシャルに使用します。例6-10に、仮想プロパティに関連付けられているデータを取得するための、テナント1のCustomerクラスのコードを示します。

例6-10 仮想プロパティに関連付けられているデータを提供するためのテナント1のコード

...
Customer customer = new Customer();

//Set Customer's real properties
customer.setFirstName("Jane");
customer.setLastName("Doe");

Address billingAddress = new Address();
billingAddress.setStreet("1 Billing Street");
customer.setBillingAddress(billingAddress);

//Set Customer's virtual 'middleName' property
customer.put("middleName", "Anne");

//Set Customer's virtual 'shippingAddress' property
Address shippingAddress = new Address();
shippingAddress.setStreet("2 Shipping Road");
customer.put("shippingAddress", shippingAddress);

List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
customer.put("phoneNumbers", phoneNumbers);

PhoneNumber workPhoneNumber = new PhoneNumber();
workPhoneNumber.setNumber("555-WORK");
//Set the PhoneNumber's virtual 'type' property
workPhoneNumber.put("type", "WORK");
phoneNumbers.add(workPhoneNumber);

PhoneNumber homePhoneNumber = new PhoneNumber();
homePhoneNumber.setNumber("555-HOME");
//Set the PhoneNumber's virtual 'type' property
homePhoneNumber.put("type", "HOME");
phoneNumbers.add(homePhoneNumber);

Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "examples/virtual/binding-tenant1.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class, Address.class}, properties);

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
...

例6-11に、テナント1のCustomerクラスからのXML出力を示します。

例6-11 テナント1のCustomerクラスからのXML出力

<?xml version="1.0" encoding="UTF-8"?>
<customer>
<firstName>Jane</firstName>
<middleName>Anne</middleName>
<lastName>Doe</lastName>
<billingAddress>
<street>1 Billing Street</street>
</billingAddress>
<shippingAddress>
<street>2 Shipping Road</street>
</shippingAddress>
<phoneNumber type="WORK">555-WORK</phoneNumber>
<phoneNumber type="HOME">555-HOME</phoneNumber>
</customer>

テナント2

2番目のテナントは、オンデマンドの映画や音楽を提供するストリーミング・メディア・プロバイダです。ここでは、コア・モデルに対して別のセットの拡張機能が必要になります。

- 1つの連絡先電話番号

このテナントの場合、実際のプロパティのマッピングのカスタマイズにもマッピング・ファイルを使用します。

例6-12に、binding-tenant2.xmlマッピング・ファイルを示します。

例6-12 テナント2の仮想プロパティの定義

<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="examples.virtual">
<xml-schema namespace="urn:tenant1" element-form-default="QUALIFIED"/>
<java-types>
<java-type name="Customer">
<xml-type prop-order="firstName lastName billingAddress phoneNumber"/>
<java-attributes>
<xml-attribute java-attribute="firstName"/>
<xml-attribute java-attribute="lastName"/>
<xml-element java-attribute="billingAddress" name="address"/>
<xml-element
java-attribute="phoneNumber"
type="examples.virtual.PhoneNumber"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>

例6-13に、仮想プロパティに関連付けられているデータを取得するための、テナント2のCustomerクラスのコードを示します。

例6-13 仮想プロパティに関連付けられているデータを提供するためのテナント2のコード

...
Customer customer = new Customer();
customer.setFirstName("Jane");
customer.setLastName("Doe");

Address billingAddress = new Address();
billingAddress.setStreet("1 Billing Street");
customer.setBillingAddress(billingAddress);

PhoneNumber phoneNumber = new PhoneNumber();
phoneNumber.setNumber("555-WORK");
customer.put("phoneNumber", phoneNumber);

Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "examples/virtual/binding-tenant2.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class, Address.class}, properties);

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
...

例6-14に、テナント2のCustomerクラスからのXML出力を示します。

例6-14 テナント2のCustomerクラスからのXML出力

<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns="urn:tenant1" firstName="Jane" lastName="Doe">
<address>
<street>1 Billing Street</street>
</address>
<phoneNumber>555-WORK</phoneNumber>
</customer>

6.4 単一表マルチテナントの使用

SaaSを実装するため重要な要素は、テナントが自分のデータのみを操作できるようにしながら、複数のアプリケーション・テナントが共有の永続性スキーマを使用できるようにすることです。単一表マルチテナントでは、すべてのアプリケーション・テナントに対して1つの表を使用し、特定のアプリケーション・コンテキスと値が設定されたテナント識別子列に基づいてアプリケーション・テナントを区別します。アプリケーションでは、必要な数の識別子列を構成することも、デフォルト動作を使用することもできます。単一表マルチテナントの詳細は、次を参照してください。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Single-Table_Multi-Tenancy

この項の内容は次のとおりです。

- 6.4.1項「主なタスク」

- 6.4.2項「その他の参考資料」

6.4.1 主なタスク

この項のタスクでは、SaaS環境で動作するように設計されたアプリケーションを作成する際に、単一表マルチテナントを使用する手順を説明します。

この項のタスクは次のとおりです。

- タスク1: 単一表マルチテナントの有効化

- タスク2: テナント識別子列の指定

- タスク3: 実行時の識別子列の使用

6.4.1.1 タスク1: 単一表マルチテナントの有効化

単一表マルチテナントは、@Multitenant注釈またはORM XMLファイルの<multitenant>要素を使用するか、注釈とXMLを一緒に使用して、宣言することにより有効にできます。

@Multitenant注釈の使用

@Multitenant注釈を使用する場合は、@Entityまたは@MappedSuperclass注釈とともにこの注釈を指定して、SINGLE_TABLE属性を指定します。次に例を示します。

@Entity
@Multitenant(SINGLE_TABLE)
public class Employee {
}

SINGLE_TABLE属性は、指定されたエンティティに関連付けられている表(TableおよびSecondaryTable)をテナント間で共有できることを示します。

<multitenant>要素の使用

<multitenant>要素を使用する場合は、<entity>要素内にこの要素を指定します。次に例を示します。

<entity class="model.Employee">
<multitenant type="SINGLE_TABLE">
...
</multitenant>
...
</entity>

6.4.1.2 タスク2: テナント識別子列の指定

識別子列は、関連付けられているアプリケーション・コンテキストとともに使用して、表のどの行にアプリケーション・テナントがアクセスできるかを示します。複数のテナント識別子列を指定できます。テナント識別子列を指定しないと、TENANT_IDという名前のデフォルト列が、デフォルトのeclipselink.tenant-idコンテキスト・プロパティとともに使用されます。表またはセカンダリ表を明示的に指定しないかぎり、テナント識別子列はプライマリ表に存在すると仮定されます。デフォルト動作を変更する方法は、次を参照してください。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Single-Table_Multi-Tenancy#Defining_Persistence_Unit_and_Entity_Mappings_Defaults

テナント識別子列は、@TenantDiscriminatorColumnまたは@TenantDiscriminatorColumns注釈を使用するか、ORM XMLファイルで<tenant-discriminator-column>要素を使用して、宣言することにより指定できます。

@TenantDiscriminatorColumn注釈の使用

@TenantDiscriminatorColumn注釈を使用する場合は、@Entityまたは@MappedSuperclass注釈とともにこの注釈を指定して、nameおよびcontextProperty属性を指定します。次に例を示します。

@Entity
@Multitenant(SINGLE_TABLE)
@TenantDiscriminatorColumn(name = "TENANT", contextProperty = "multi-tenant.id")
public class Employee {
}

複数の列を指定する場合は、複数の@TenantDiscriminatorColumn注釈を@TenantDiscriminatorColumns注釈内に指定し、プライマリ表に列がない場合は、列がある表を指定します。次に例を示します。

@Entity
@Table(name = "EMPLOYEE")
@SecondaryTable(name = "RESPONSIBILITIES")
@Multitenant(SINGLE_TABLE)
@TenantDiscriminatorColumns({
@TenantDiscriminatorColumn(name = "TENANT_ID",
contextProperty = "employee-tenant.id", length = 20)
@TenantDiscriminatorColumn(name = "TENANT_CODE",
contextProperty = "employee-tenant.code", discriminatorType = STRING,
table = "RESPONSIBILITIES")
}
)
public Employee() {
...
}

<tenant-discriminator-column>要素の使用

<tenant-discriminator-column>要素を使用する場合は、<multitenant>要素内にこの要素を指定して、nameおよびcontext-property属性を指定します。次に例を示します。

<entity class="model.Employee">
<multitenant>
<tenant-discriminator-column name="TENANT"
context-property="multi-tenant.id"/>
</multitenant>
...
</entity>

複数の列を指定する場合は、追加の<tenant-discriminator-column>要素を指定して、プライマリ表に列がない場合は、列がある表を指定します。次に例を示します。

<entity class="model.Employee">
<multitenant type="SINGLE_TABLE">
<tenant-discriminator-column name="TENANT_ID"
context-property="employee-tenant.id" length="20"/>
<tenant-discriminator-column name="TENANT_CODE"
context-property="employee-tenant.id" discriminator-type="STRING"
table="RESPONSIBILITIES"/>
</multitenant>
<table name="EMPLOYEE"/>
<secondary-table name="RESPONSIBILITIES"/>
...
</entity>

テナント識別子列のマッピング

テナント識別子列は、主キーまたは別の列にマッピングできます。次の例では、DDL生成時に、表の主キーにテナント識別子列をマッピングしています。

@Entity
@Table(name = "ADDRESS")
@Multitenant
@TenantDiscriminatorColumn(name = "TENANT", contextProperty = "tenant.id",
primaryKey = true)
public Address() {
...
}

オブジェクト・エンティティの一部として、識別子列が主キーにマップされるようにするには、列をマップする必要があります。次に例を示します。

@Id
@Column("TENANT")
public int tenant;

次の例では、ORM XMLファイルの主キーにテナント識別子列をマッピングしています。

<entity class="model.Address">
<multitenant>
<tenant-discriminator-column name="TENANT"
context-property="multi-tenant.id" primary-key="true"/>
</multitenant>
<table name="ADDRESS"/>
...
</entity>

次の例では、別の列名AGEにテナント識別子列をマッピングしています。

@Entity
@Table(name = "Player")
@Multitenant
@TenantDiscriminatorColumn(name = "AGE", contextProperty = "tenant.age")
public Player() {
...

@Basic
@Column(name="AGE", insertable="false", updatable="false")
public int age;
}

また、ORM XMLファイルでは、次のようになります。

<entity class="model.Player">
<multi-tenant>
<tenant-discriminator-column name="AGE" context-property="tenant.age"/>
</multi-tenant>
<table name="PLAYER"/>
...
<attributes>
<basic name="age" insertable="false" updatable="false">
<column name="AGE"/>
</basic>
...
</attributes>
...
</entity>

実行時のコンテキスト・プロパティの指定

実行時には、create entity manager factoryコールに渡される永続性ユニット定義を使用するか、個々のエンティティ・マネージャに設定して、コンテキスト・プロパティ構成を指定できます。次に例を示します。

<persistence-unit name="multi-tenant">
...
<properties>
<property name="tenant.id" value="707"/>
...
</properties>
</persistence-unit>

または、コードで次のように記述することもできます。

HashMap properties = new HashMap();
properties.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, "707");
EntityManager em = Persistence.createEntityManagerFactory("multi-tenant-pu",
properties).createEntityManager();

エンティティ・マネージャのプロパティ定義は、次のとおりです。

EntityManager em =
Persistence.createEntityManagerFactory("multi-tenant-pu").createEntityManager();
em.beginTransaction();
em.setProperty("other.tenant.id.property", "707");
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "707");
...

6.4.1.3 タスク3: 実行時の識別子列の使用

テナント識別子列は、エンティティ・マネージャの操作および問合せを介して、実行時に使用できます。テナント識別子列と値は、次のエンティティ・マネージャの操作でサポートされます。

- persist()

- find()

- refresh()

テナント識別子列と値は、次のエンティティ・マネージャの問合せでサポートされます。

- 名前付き問合せ

- すべて更新

- すべて削除

注意:

マルチテナントは、名前付きのネイティブ問合せではサポートされません。マルチテナント環境で名前付きのネイティブ問合せを使用する場合は、マルチテナントに関する問題を問合せで直接に手動で処理してください。一般に、マルチテナント環境では名前付きのネイティブ問合せを使用しないことをお薦めします。

6.4.2 その他の参考資料

次の参照資料を使用できます。

- 6.4.2.1項「コード・サンプル」

- 6.4.2.2項「関連Javadoc」

6.4.2.1 コード・サンプル

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant

http://wiki.eclipse.org/EclipseLink/Examples/MySports

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant/VPD

6.4.2.2 関連Javadoc

詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』の次のAPIを参照してください。

- org.eclipse.persistence.annotations.Multitenant

- org.eclipse.persistence.annotations.TenantDiscriminatorColumn

- org.eclipse.persistence.annotations.TenantDiscriminatorColumns

6.5 外部メタデータ・ソースの使用

TopLinkでは、実行中のアプリケーションの外部にあるメタデータ・ソースにマッピング情報をストアできます。マッピング情報は、アプリケーションが永続性ユニットを作成するときに取得されるので、デプロイされたアプリケーションで動的にマッピングのオーバーライドまたは拡張を行えます。

6.5.1 eclipselink-orm.xmlファイルの外部使用

TopLinkでは、eclipselink-orm.xmlファイルを使用し、高度なマッピングのタイプおよびオプションをサポートできます。このファイルで、標準のJPA orm.xmlマッピング構成ファイルをオーバーライドできます。

6.5.2 主なタスク

この項には、次の項目が含まれます。

- タスク1: 永続性ユニットの構成

- タスク2: サーバーの構成

6.5.2.1 タスク1: 永続性ユニットの構成

永続性ユニットを構成して、次の方法で外部メタデータを使用できます。

- 6.5.2.1.1項「固定場所へのアクセス」

- 6.5.2.1.2項「アプリケーション・コンテキスト・ベースの場所へのアクセス」

6.5.2.1.1 固定場所へのアクセス

追加のマッピング情報が指定されたeclipselink-orm.xmlファイルなどの外部ファイルにアクセスする最も簡単な方法は、Webサーバー上の固定URLでファイルを使用できるようにすることです。

例6-15に示すeclipselink.metadata-source.xml.urlプロパティを使用して、場所を指定します。

例6-15 固定場所

<property name="eclipselink.metadata-source" value="XML"/>
<property name="eclipselink.metadata-source.xml.url" value="http://myserverlocation/"/>

6.5.2.1.2 アプリケーション・コンテキスト・ベースの場所へのアクセス

マルチテナント・アプリケーションでテナント固有の拡張機能を提供する場合のように、要件がさらに複雑な場合は、アプリケーション・コンテキストに基づいて外部メタデータの場所を指定できます。

例6-16に示すMetadataSourceインタフェースを実装して、場所を指定します。

例6-16 固定場所

<property name="eclipselink.metadata-source" value="mypackage.MyMetadataSource"/>
<property name="eclipselink.metadata-source.xml.url" value="foo://bar"/>

例6-17に、テナントに基づいて、特定のマッピング・ファイルを返す方法を示します。

例6-17 テナント固有のマッピング・ファイル

public class AdminMetadataSource extends XMLMetadataSource {

@Override
public XMLEntityMappings getEntityMappings(Map<String, Object> properties, ClassLoader classLoader, SessionLog log) {
String leagueId = (String) properties.get(LEAGUE_CONTEXT);
properties.put(PersistenceUnitProperties.METADATA_SOURCE_XML_URL, "http://myserverlocation/rest/" + leagueId + "/orm");
return super.getEntityMappings(properties, classLoader, log);
}
}

6.5.2.2 タスク2: サーバーの構成

メタデータ・ファイルにアクセスするには、次のいずれかの方法を使用して、マッピング・ファイルへのURLアクセスをサーバーで実現する必要があります。

- 静的なファイル提供サービス

- 自分のマッピング・ファイル、またはストアされているマッピング情報からオンデマンドで作成されるマッピング・ファイルを使用するサーバーベースのソリューション

- その他のWebテクノロジ

6.5.3 その他の参考資料

JPAデプロイメントの詳細は、JPA仕様の次の項(http://jcp.org/en/jsr/detail?id=317)を参照してください。

- 7.2項「Bootstrapping in Java SE Environments」

- 第7章「Container and Provider Contracts for Deployment and Bootstrapping」

6.5.3.1 Javadoc

詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』の次のAPIを参照してください。

- PersistenceUnitPropertiesクラス

7 XMLへのJPAのマッピング

この章では、POJO (Plain Old Java Object)をXMLにマッピングするためのJava EE標準であるJava Architecture for XML Binding (JAXB)でJPAを使用する方法、およびJPAエンティティをXMLにマッピングするMapping Objects to XML (MOXy)拡張機能を使用する方法について説明します。XMLへのJPAエンティティのマッピングは、RESTful Webサービス(JAX-RS)用のJava API、XML Webサービス(JAX-WS)用のJava APIまたはSpringを使用するデータ・アクセス・サービスを作成する場合に便利です。

この章には次のトピックが含まれます:

- 7.1項「JPAからXMLへのマッピングの概念の理解」

- 7.2項「XMLへのJPAエンティティのバインディング」

- 7.3項「XMLテキスト・ノードへの単純なJava値のマッピング」

- 7.4項「XMLメタデータ表現を使用したJAXB注釈のオーバーライド」

- 7.5項「マッピングに対するXPath述語の使用」

- 7.6項「動的JAXB/MOXyの使用」

7.1 JPAからXMLへのマッピングの概念の理解

この章では、XMLにJPAエンティティをマッピングする一般的な方法をいくつか示します。次の例を扱うには、JAXB、MOXy、XMLバインディング、JAXB注釈のオーバーライド方法などのJPAからXMLへのマッピングの全体的な概念を理解している必要があります。次の項では、これらの概念の基礎的なことがらを説明します。

- 7.1.1項「XMLバインディングの理解」

- 7.1.2項「JAXBの理解」

- 7.1.3項「MOXyの理解」

- 7.1.4項「XMLデータ表現の理解」

7.1.1 XMLバインディングの理解

XMLバインディングとは、コンピュータのメモリーのオブジェクトとして、XML文書内に情報を表現する方法です。これにより、Domain Object Model (DOM)、Simple API for XML (SAX)またはStreaming API for XML (StAX)を使用してXML自身の直接表現からデータを取得しなくても、オブジェクトからXML内のデータにアクセスできるようになります。バインディングする際に、JAXBでは、JPAエンティティのグラフにツリー構造が適用されます。グラフの複数ツリー表現は可能で、選択されたルート・オブジェクトおよびリレーションシップがトラバースする方向に依存します。

JAXBによるXMLバインディングの例は7.2項「XMLへのJPAエンティティのバインディング」にあります。

7.1.2 JAXBの理解

JAXBは、XML文書をJava形式でJavaプログラムに提示することにより、JavaプログラムがXML文書にアクセスできようにするJava APIです。このプロセスはバインディングと呼ばれ、コンピュータ・メモリー内のオブジェクトとして、XML文書内に情報が表現されます。これにより、Domain Object Model (DOM)またはStreaming API for XML (SAX)を使用してXML自身の直接表現からデータを取得しなくても、オブジェクトからXML内のデータにアクセスできるようになります。通常、XMLバインディングをJPAエンティティとともに使用し、JAX-WSまたはJAX-RSの実装を利用して、データ・アクセス・サービスを作成します。これら両方のWebサービス標準では、JAXBがデフォルトのバインディング・レイヤーとして使用されています。このサービスにより、クライアント・コンピュータでJavaが使用されている場合とそうでない場合がある複数のコンピュータ間で、JPAによって公開されたデータにアクセスできるようになります。

JAXBでは、注釈の拡張セットを使用して、JavaからXMLへのマッピングのバインディング・ルールを定義します。これらの注釈は、TopLink APIのjavax.xml.bind.*パッケージのサブクラスになっています。これらの注釈の詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』を参照してください。

JAXBの詳細は、次の『Java Architecture for XML Binding (JAXB)』を参照してください。

http://www.eclipse.org/eclipselink/moxy.php

7.1.3 MOXyの理解

MOXyはTopLinkのJAXB実装です。これにより、POJOモデルをXMLスキーマにマップできるようになるので、JPAからXMLへのマッピングを作成する能力が大幅に拡張します。MOXyでは、javax.xml.bind.annotationのすべての標準JAXB注釈のサポートに加えて、org.eclipse.persistence.oxm.annotationsパッケージの独自の拡張機能も提供されています。これら後者の注釈を標準の注釈とともに使用すれば、JAXBの実用性をさらに拡張できます。MOXyは最適化されたJAXB実装なので、拡張機能を明示的に使用してもしなくても実装できます。MOXyには、次の利点があります。

- 独自のクラスを独自のXMLスキーマにマップできるようになります。このプロセスを「中間突合せマッピング」と呼びます。これにより、マップされたクラスを1つのXMLスキーマに静的にカップリングしなくてすみます。

- 複合キー・マッピングやバックポインタとのリレーションシップのマッピングなど、JPAからXMLへのマッピングの重要な問題に対処するための固有の機能が用意されています。

- 既存のJPAモデルを業界標準のスキーマにマップできます。

- MOXyマッピングとOracle TopLinkの永続性フレームワークを組み合せれば、JCA経由でデータを対話的に処理できます。

- 数種類のシナリオで優れたパフォーマンスが得られます。

MOXyの詳細は、次の『MOXy FAQ』を参照してください。

http://wiki.eclipse.org/EclipseLink/FAQ/WhatIsMOXy

7.1.4 XMLデータ表現の理解

JAXB/MOXyは、JPAからXMLにマップするために、いつでも最も効果的な方法であるとはかぎりません。たとえば、次の場合にはJAXBを使用しません。

- サード・パーティのクラスにメタデータを指定する必要があるが、ソースにアクセスできない場合。

- 複数のXMLスキーマにオブジェクト・モデルをマップする必要がある場合。JAXBのルールでは、注釈を使用して複数のマッピングを適用することはできません。

- オブジェクト・モデルにすでに多くの注釈(たとえば、JPA、Spring、JSR-303などのサービスから)が含まれていて、他の場所でメタデータを指定する必要がある場合。

これらの状況および類似の状況では、eclipselink_oxm.xmlファイルを公開して、XMLデータ表現を使用できます。

XMLメタデータは、次の2つのモードで動作します。

- 注釈で指定されたメタデータに追加します。これは、次の場合に便利です。

- XML表現のバージョンのひとつが注釈に定義されており、XMLメタデータを使用して将来のバージョンのメタデータを微調整する場合。

- 標準のJAXB注釈を使用し、かつMOXy拡張機能用のXMLメタデータを使用する場合。このようにすると、コンパイル時の依存関係がオブジェクト・モデルに新たに生じることはありません。

- 注釈メタデータを完全に置換します。これは、様々なXML表現にマップする必要がある場合に便利です。

XMLデータ表現の使用方法の詳細は、7.4項「XMLメタデータ表現を使用したJAXB注釈のオーバーライド」を参照してください。

7.2 XMLへのJPAエンティティのバインディング

次の例は、JAXB注釈を使用してJPAエンティティをXMLにバインドする方法を示しています。バインディングの詳細は、7.1.1項「XMLバインディングの理解」を参照してください。JAXBの詳細は、7.1.2項「JAXBの理解」を参照してください。

- 7.2.1項「XMLへのJPAリレーションシップのバインディング」

- 7.2.2項「XMLへの複合主キーのバインディング」

- 7.2.3項「XMLへの埋込みIDクラスのバインディング」

7.2.1 XMLへのJPAリレーションシップのバインディング

次の演習問題は、JAXBを使用して一連のJPAエンティティからXML表現を導出する方法を示しています。このプロセスは「バインディング」と呼ばれます(XMLバインディングの詳細は、7.2項「XMLへのJPAエンティティのバインディング」を参照してください)。これらの例は、次の2つの一般的なJPAリレーションシップをバインドする方法を示しています。

- 私有のリレーションシップ

- 共有参照のリレーションシップ

従業員エンティティを、その従業員の電話番号、住所および部門にマッピングしています。

7.2.1.1 タスク1: アクセス・タイプおよびインポート・パッケージの定義

次のすべての例で、同じアクセッサ・タイプFIELDを使用しているので、JAXB注釈@XmlAccessorTypeを使用してパッケージ・レベルでアクセッサ・タイプを定義します。この時点で、必要なパッケージをインポートすることもできます。

@XmlAccessorType(XmlAccessType.FIELD)
package com.example.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

7.2.1.2 タスク2: 私有のリレーションシップのマッピング

「私有」のリレーションシップは、ターゲット・オブジェクトが1つのソース・オブジェクトのみによって参照されている場合に発生します。このタイプのリレーションシップは、1対1および埋込み、または1対多のどちらの場合にも可能です。

このタスクでは、Employeeエンティティと、AddressおよびPhoneNumberエンティティの間のこれら両方のタイプのリレーションシップに対して双方向のマッピングを作成する方法を示します。

7.2.1.2.1 1対1および埋込みのリレーションシップのマッピング

JPAの@OneToOneおよび@Embedded注釈は、ソース・エンティティの1つのインスタンスのみが、同じターゲット・エンティティ・インスタンスを参照できることを示しています。この例は、EmployeeエンティティをAddressエンティティにマップする方法、およびその逆にマップする方法を示しています。従業員は1つの住所のみに関連付けられるので、1対1マッピングと見なされます。このリレーションシップは双方向、つまりEmployeeはAddressを指し、さらにEmployeeを逆に指すので、TopLinkの拡張機能@XmlInverseReferenceを使用してバックポインタを表現しています。

1対1および埋込みマッピングを作成するには:

1. 7.2.1.1項「タスク1: アクセッサ・タイプおよびインポート・パッケージの定義」の説明に従って、アクセッサ・タイプFIELDがパッケージ・レベルに定義されていることを確認します。

2. @OneToOne注釈をEmployeeエンティティに挿入することにより、リレーションシップの1方向(この場合は、Addressのemployeeプロパティ)をマップします。

@OneToOne(mappedBy="resident")
private Address residence;

mappedBy引数は、リレーションシップがresidentフィールドによって所有されていることを示します。

3. @OneToOneおよび@XmlInverseMapping注釈をAddressエンティティに挿入することにより、戻り方向(この場合は、Employeeのaddressプロパティ)をマップします。

@OneToOne
@JoinColumn(name="E_ID")
@XmlInverseReference(mappedBy="residence")
private Employee resident;

mappedByフィールドは、このリレーションシップがresidenceフィールドによって所有されていることを示します。@JoinColumnは、外部キーが格納される列を示します。

エンティティは、例7-1および例7-2に示すエンティティと同じように指定してください。

7.2.1.2.2 1対多のリレーションシップのマッピング

JPAの@OneToMany注釈は、ソース・エンティティの1つのインスタンスが同じターゲット・エンティティの複数のエンティティを参照できることを示しています。たとえば、1人の従業員に、固定電話、携帯電話、連絡先の電話、勤務先の予備の電話番号など、複数の電話番号がある場合があります。異なる各番号がPhoneNumberエンティティのインスタンスになり、1つのEmployeeエンティティが各インスタンスを指す場合があります。

このタスクでは、従業員をその従業員の電話番号の1つにマッピングして、逆方向にもマッピングします。EmployeeとPhoneNumberのリレーションシップは双方向なので、この例でも、TopLinkの拡張機能@XmlInverseReferenceを使用してバックポインタをマップします。

1対多マッピングを作成するには、次のようにします。

1. 7.2.1.1項「タスク1: アクセッサ・タイプおよびインポート・パッケージの定義」の説明に従って、アクセッサ・タイプFIELDがパッケージ・レベルに定義されていることを確認します。

2. @OneToMany注釈をEmployeeエンティティに挿入することにより、リレーションシップの1方向(この場合は、PhoneNumberのemployeeプロパティ)をマップします。

@OneToMany(mappedBy="contact")
private List<PhoneNumber> contactNumber;

mappedByフィールドは、このリレーションシップがcontactフィールドによって所有されていることを示します。

3. @ManyToOneおよび@XmlInverseMapping注釈をPhoneNumberエンティティに挿入することにより、戻り方向(この場合は、Employeeのphone numberプロパティ)をマップします。

@ManyToOne
@JoinColumn(name="E_ID", referencedColumnName = "E_ID")
@XmlInverseReference(mappedBy="contactNumber")
private Employee contact;

mappedByフィールドは、このリレーションシップがcontactNumberフィールドによって所有されていることを示します。@JoinColumnは、外部キーが格納される列(name="E_ID")および外部キーによって参照される列(referencedColumnName = "E_ID")を示しています。

エンティティは、例7-1および例7-3に示すエンティティと同じように指定してください。

7.2.1.3 タスク3: 共有参照リレーションシップのマッピング

共有参照リレーションシップは、ターゲット・オブジェクトが複数のソース・オブジェクトによって参照されている場合に発生します。たとえば、IT、人事、財務などの複数の部門にビジネスが区分されている場合があります。これらの各部門には、職責、賃金水準、勤務先などの異なる複数の従業員がいます。部門および従業員を管理するには、共有参照リレーションシップが必要になります。

XMLのネストを使用して共有参照リレーションシップを安全に表現することはできないので、キー・リレーションシップを使用します。JPAエンティティのIDフィールドを利用するには、TopLinkのJAXB @XmlID注釈を文字列以外のフィールドとプロパティに、@XmlIDREFを文字列のフィールドとプロパティに使用する必要があります。

この項では、多対1の共有参照リレーションシップおよび多対多の共有参照リレーションシップのマップ方法を示す例を示します。

7.2.1.3.1 多対1の共有参照リレーションシップのマッピング

多対1のマッピングでは、ソース・エンティティの1つ以上のインスタンスが同じターゲット・エンティティのインスタンスを参照できます。この例は、従業員の複数の電話番号のいずれか1つに従業員をマップする方法を示しています。

多対1の共有参照リレーションシップをマップするには:

1. 7.2.1.1項「タスク1: アクセッサ・タイプおよびインポート・パッケージの定義」の説明に従って、アクセッサ・タイプFIELDがパッケージ・レベルに定義されていることを確認します。

2. @ManyToOne注釈をPhoneNumberエンティティに挿入することにより、リレーションシップの1方向(この場合は、Employeeのphone numberプロパティ)をマップします。

@ManyToOne
@JoinColumn(name="E_ID", referencedColumnName = "E_ID")
@XmlIDREF
private Employee contact;

@JoinColumnは、外部キーが格納される列(name="E_ID")および外部キーによって参照される列(referencedColumnName = "E_ID")を示しています。@XmlIDREF注釈は、これが、対応する表の主キーになることを示しています。

3. @OneToManyおよび@XmlInverseMapping注釈をAddressエンティティに挿入することにより、戻り方向(この場合は、PhoneNumberのemployeeプロパティ)をマップします。

@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;

両方の注釈のmappedByフィールドは、このリレーションシップがcontactフィールドによって所有されていることを示しています。

エンティティは、例7-1および例7-3に示すエンティティと同じように指定してください。

7.2.1.3.2 多対多の共有参照リレーションシップのマッピング

@ManyToMany注釈は、ソース・エンティティの1つ以上のインスタンスが、ターゲット・エンティティの1つ以上のインスタンスを参照できることを示しています。DepartmentとEmployeeのリレーションシップは双方向なので、この例でも、TopLinkの@XmlInverseReference注釈を使用してバックポインタを表現しています。

多対多の共有参照リレーションシップをマップするには、次を実行します:

1. 7.2.1.1項「タスク1: アクセッサ・タイプおよびインポート・パッケージの定義」の説明に従って、アクセッサ・タイプFIELDがパッケージ・レベルに定義されていることを確認します。

2. 次のコードを挿入して、Departmentエンティティを作成します。

@Entity
public class Department {

3. 次のコードを挿入して、多対多のリレーションシップおよびエンティティの結合表を、このエンティティに定義します。

@ManyToMany    @JoinTable(name="DEPT_EMP", joinColumns =         @JoinColumn(name="D_ID", referencedColumnName = "D_ID"),             inverseJoinColumns = @JoinColumn(name="E_ID",                 referencedColumnName = "E_ID"))

このコードにより、DEPT_EMPという結合表が作成され、外部キーが格納される列(name="E_ID")および外部キーによって参照される列(referencedColumnName = "E_ID")が指定されます。さらに、関連付けの逆側のプライマリ表も指定されます。

4. 最初のマッピング(この場合は、Departmentのemployeeプロパティ)を完了し、次のコードを挿入して、それをこのエンティティの外部キーにします。

@XmlIDREF
private List<Employee> member;

5. 7.2.1.2.1項「1対1および埋込みリレーションシップのマッピング」で作成したEmployeeエンティティに、次のコードを挿入して、eIdがJPA (@Id注釈)およびJAXB (@XmlID注釈)の主キーであることを指定します。

@Id
@Column(name="E_ID")
@XmlID
private BigDecimal eId;

6. さらにEmployeeエンティティに、次のコードを挿入して、リターン・マッピングを指定します。

@ManyToMany(mappedBy="member")
@XmlInverseReference(mappedBy="member")
private List<Department> team;

エンティティは、例7-1および例7-4に示すエンティティと同じように指定してください。

7.2.1.4 JPAエンティティ

マッピングが作成されると、エンティティは次の例のようになります。

- 例7-1「Employeeエンティティ」

- 例7-2「Addressエンティティ」

- 例7-3「PhoneNumberエンティティ」

- 例7-4「Departmentエンティティ」

注意:

スペースを節約するために、パッケージ名、import文、およびget/setメソッドは、コード・サンプルから除かれています。すべての例で、標準のJPA注釈が使用されています。

例7-1 Employeeエンティティ

@Entity
public class Employee {

@Id
@Column(name="E_ID")
private BigDecimal eId;

private String name;

@OneToOne(mappedBy="resident")
private Address residence;

@OneToMany(mappedBy="contact")
private List<PhoneNumber> contactNumber;

@ManyToMany(mappedBy="member")
private List<Department> team;

}

例7-2 Addressエンティティ

@Entity
public class Address {

@Id
@Column(name="E_ID", insertable=false, updatable=false)
private BigDecimal eId;

private String city;

private String street;

@OneToOne
@JoinColumn(name="E_ID")
private Employee resident;

}

例7-3 PhoneNumberエンティティ

@Entity
@Table(name="PHONE_NUMBER")
public class PhoneNumber {

@Id
@Column(name="P_ID")
private BigDecimal pId;

@ManyToOne
@JoinColumn(name="E_ID", referencedColumnName = "E_ID")
private Employee contact;

private String num;

}

例7-4 Departmentエンティティ

@Entity
public class Department {

@Id
@Column(name="D_ID")
private BigDecimal dId;

private String name;

@ManyToMany
@JoinTable(name="DEPT_EMP", joinColumns =
@JoinColumn(name="D_ID", referencedColumnName = "D_ID"),
inverseJoinColumns = @JoinColumn(name="E_ID",
referencedColumnName = "E_ID"))
private List<Employee> member;

}

7.2.2 XMLへの複合主キーのバインディング

JPAエンティティに複合主キーがある場合、JAXB注釈およびOracle TopLinkの特定の拡張機能を使用して複合主キーをバインドできます。次に例を示します。

7.2.2.1 タスク1: XMLアクセッサ・タイプの定義

7.2.1.1項「タスク1: アクセッサ・タイプおよびインポート・パッケージの定義」の説明に従って、アクセッサ・タイプにFIELDを定義します。

7.2.2.2 タスク2: ターゲット・オブジェクトの作成

ターゲット・オブジェクトを作成するには、次を実行します:

1. エンティティの複数のフィールドまたはプロパティにマップするためのEmployeeIDという複合主キー・クラスを指定して、Employeeを作成します。

@Entity
@IdClass(EmployeeId.class)
public class Employee {

2. エンティティの最初の主キーeIdを指定して、列にマップします。

@Id
@Column(name="E_ID")
@XmlID
private BigDecimal eId;

3. 2番目の主キーcountryを指定します。この場合、@XmlID.Creで注釈を付けられるのは1つのプロパティ(ここではeId)のみなので、@XmlKeyを使用して主キーを指定する必要があります。

@Id
@XmlKey
private String country;

@XmlKey注釈により、ソース・オブジェクトの@XmlJoinNode注釈を介したキーに基づくマッピングを使用して参照されるキーとして、プロパティがマーク付けされます。スキーマ・タイプIDにプロパティをバインドする必要がない点以外は@XmlKey注釈に似ています。これは、@XmlKey注釈の一般的な適用方法です。

4. 次のコードを挿入して、PhoneNumberのEmployeeプロパティの1対多マッピングを作成します。

@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;

Employeeエンティティは例7-5のようになります。

例7-5 複合主キーが設定されたEmployeeエンティティ

@Entity
@IdClass(EmployeeId.class)
public class Employee {

@Id
@Column(name="E_ID")
@XmlID
private BigDecimal eId;

@Id
@XmlKey
private String country;

@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;

}

7.2.2.3 タスク3: ソース・オブジェクトの作成

このタスクでは、ソース・オブジェクトPhoneNumberエンティティを作成します。ターゲット・オブジェクトに複合キーがあるので、Oracle TopLinkの@XmlJoinNodes注釈を使用してマッピングを設定する必要があります。

ソース・オブジェクトを作成するには:

1. PhoneNumberエンティティを作成します。

@Entity
public class PhoneNumber {

2. 多対1のリレーションシップを作成して、結合列を定義します。

@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})

3. Oracle TopLinkの@XmlJoinNodes注釈を使用して、マッピングを設定します。

@XmlJoinNodes( {
@XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
@XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})

4. contactプロパティを定義します。

private Employee contact;

}

ターゲット・オブジェクトは例7-6のようになります。

例7-6 PhoneNumberエンティティ

@Entity
public class PhoneNumber {

@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
@XmlJoinNodes( {
@XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
@XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})
private Employee contact;

}

7.2.3 XMLへの埋込みIDクラスのバインディング

埋込みIDでは、エンティティの主キーを格納する別個のEmbeddable Javaクラスを定義します。これは@EmbeddedId注釈を使用して定義します。埋込みIDのEmbeddableクラスには、基本マッピングを使用してエンティティの各ID属性を定義する必要があります。埋込みIDのEmbeddableのすべての属性は、主キーの一部であると見なされます。この演習では、JPAエンティティに埋込みIDクラスがある場合に、JAXBを使用して一連のJPAエンティティからXML表現を導出する方法を示します。

7.2.3.1 タスク1: XMLアクセッサ・タイプの定義

7.2.1.1項「タスク1: アクセッサ・タイプおよびインポート・パッケージの定義」の説明に従って、XMLアクセッサ・タイプをFIELDと定義します。

7.2.3.2 タスク2: ターゲット・オブジェクトの作成

ターゲット・オブジェクトはEmployeeというエンティティで、従業員の連絡先電話番号のマッピングが格納されています。このターゲット・オブジェクトを作成するには、DescriptorCustomizerインタフェースを実装する必要があるので、TopLinkの@XmlCustomizer注釈を含める必要があります。また、リレーションシップが双方向なので、@XmlInverseReference注釈も実装する必要があります。

ターゲット・オブジェクトを作成するには:

1. Employeeエンティティを作成します。@IdClass注釈を使用して、EmployeeIDクラスがエンティティの複数のプロパティにマップされることを指定し、@XmlCustomizer注釈を使用して、EmployeeCustomizerクラスがDescriptorCustomizerインタフェースを実装することを指定します(7.2.3.3項「タスク3: EmployeeCustomizerクラスとしてのDescriptorOrganizerの実装」を参照してください)。

@Entity
@IdClass(EmployeeId.class)
public class Employee {

2. idプロパティを定義して、埋込み可能にします。

@EmbeddedId
@XmlPath(".");
private EmployeeId id;

3. 1対多のマッピング(この場合は、PhoneNumberのemployeeプロパティ)を定義します。リレーションシップが双方向なので、@XmlInverseReferenceを使用してリターン・マッピングを定義します。mappedBy引数で示されているように、これら両方のリレーションシップはcontactフィールドによって所有されます。

@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;

完成したターゲット・オブジェクトは例7-7のようになります。

例7-7 ターゲット・オブジェクトとしてのEmployeeエンティティ

@Entity
@IdClass(EmployeeId.class)
@XmlCustomizer(EmployeeCustomizer.class)
public class Employee {

@EmbeddedId
private EmployeeId id;

@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;

}

7.2.3.3 タスク3: EmployeeCustomizerクラスとしてのDescriptorOrganizerの実装

「タスク2: ターゲット・オブジェクトの作成」では、DescriptorCustomizerはEmployeeCustomizerクラスとして実装されました。これにより、idプロパティのマッピングのXMLパス(XPath)を自分または「.」に変更して、IDを表すXMLノードをXPathに指定できるようになります。これを行うには:

1. DescriptorOrganizerクラスをEmployeeOrganizerとして実装します。

import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;

public class EmployeeCustomizer implements DescriptorCustomizer {

2. IDを表すXMLノードをXPathに指定します。

descriptor.addPrimaryKeyFieldName("eId/text()");
descriptor.addPrimaryKeyFieldName("country/text()");

EmployeeCustomizerクラスは例7-8のようになります。

例7-8 更新されたXPath情報が指定されたEmployeeCustomizerクラス

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;

public class EmployeeCustomizer implements DescriptorCustomizer {

descriptor.addPrimaryKeyFieldName("eId/text()");
descriptor.addPrimaryKeyFieldName("country/text()");
}

}

7.2.3.4 タスク4: ソース・オブジェクトの作成

この例のソース・オブジェクトには複合キーがあるので、キーが自分自身にマップされるのを防ぐために、フィールド@XmlTransientをマーク付けする必要があります。TopLinkの@XmlCustomizer注釈を使用してマッピングを設定します。

ソース・オブジェクトを作成するには、次を実行します:

1. PhoneNumberエンティティを作成し、別のクラスPhoneNumberCustomizerを指定して、DescriptorCustomizerインタフェースを実装します。

@Entity
@XmlCustomizer(PhoneNumberCustomizer.class)
public class PhoneNumber {

2. 多対1のマッピングを作成して、結合列を定義します。

@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})

3. contactプロパティを定義します。@XmlTranscient注釈を必ず使用して、このキーが自分自身にマップされないようにしてください。

@XmlTransient
private Employee contact;

完成したPhoneNumberクラスは例7-9のようになります。

例7-9 ソース・オブジェクトとしてのPhoneNumberクラス

@Entity
@XmlCustomizer(PhoneNumberCustomizer.class)
public class PhoneNumber {

@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
@XmlTransient
private Employee contact;

}

7.2.3.5 タスク5: PhoneNumberCustomizerクラスとしてのDescriptorCustomizerの実装

タスク4で追加したコードは、新しい値に対してXMLObjectReferenceMappingsを作成する必要があることを示していました。これには、DescriptorCustomizerをPhoneNumberCustomizerとして実装して、複数のキー・マッピングを追加する必要があります。これを行うには:

1. DescriptorCustomizerをPhoneNumberCustomizerとして実装します。org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMappingを必ずインポートしてください。

import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;

public class PhoneNumberCustomizer implements DescriptorCustomizer {

2. customizeメソッドで、次のマッピングを更新します。

- contactMapping.setAttributeNameを"contact"にします。

- contactMapping.addSourceToTargetKeyFieldAssociationを"contact/@eID", "eId/text()"にします。

- contactMapping.addSourceToTargetKeyFieldAssociationを"contact/@country", "country/text()"にします。

PhoneNumberCustomizerは例7-10のようになります。

例7-10 更新されたキー・マッピングが指定されたPhoneNumber Customizer

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;

public class PhoneNumberCustomizer implements DescriptorCustomizer {

public void customize(ClassDescriptor descriptor) throws Exception {
XMLObjectReferenceMapping contactMapping = new XMLObjectReferenceMapping();
contactMapping.setAttributeName("contact");
contactMapping.setReferenceClass(Employee.class);
contactMapping.addSourceToTargetKeyFieldAssociation("contact/@eID", "eId/text()");
contactMapping.addSourceToTargetKeyFieldAssociation("contact/@country", "country/text()");
descriptor.addMapping(contactMapping);
}

}

7.2.4 EclipseLinkのXMLバインディング文書の使用

前述の例で示したように、TopLinkには、JPAエンティティをXML表現にマップする標準のJAXB注釈が実装されています。EclipseLinkのXMLバインディング文書を使用して、メタデータを表現することもできます。XMLバインディングを使用してマッピング情報を実際のJavaクラスから分離できるだけでなく、次のようなさらに高度なメタデータ・タスクに使用することもできます。

- 追加のマッピング情報による、既存の注釈の増強またはオーバーライド。

- Java注釈を使用しない、すべてのマッピング情報の外部指定。

- 複数のバインディング文書間のマッピングの定義。

- 具体的なJavaフィールドに対応しない「仮想」マッピングの指定。

XMLバインディング文書の使用の詳細は、http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy/Runtime/XML_BindingsにあるJAXB/MOXyのドキュメントのXMLバインディングに関する項を参照してください。

7.3 XMLテキスト・ノードへの単純なJava値のマッピング

この項では、単純なJava値をXMLテキスト・ノードに直接マップする方法をいくつか示します。次の例を示します。

- 属性に対する値のマッピング

- テキスト・ノードに対する値のマッピング

7.3.1 属性に対する値のマッピング

この例では、JavaオブジェクトCustomerのidプロパティを、<customer>要素の属性として、そのXML表現にマップします。このXMLは例7-11のスキーマに基づいています。

例7-11 XMLスキーマの例

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="customer" type="customer-type"/>

<xsd:complexType name="customer-type">
<xsd:attribute name="id" type="xsd:integer"/>
</xsd:complexType>

</xsd:schema>

次の手順では、Javaオブジェクトのidプロパティをマップする方法、つまり、Oracle TopLinkのObject-to-XML Mapping (OXM)メタデータ形式で値を表す方法を説明します。

7.3.1.1 Javaオブジェクトからのマッピング

Javaオブジェクトからこのマッピングを作成するために重要なのは、フィールドをXML属性にマップする@XmlAttribute JAXB注釈です。このマッピングを作成するには:

1. オブジェクトを作成して、javax.xml.bind.annotation.*をインポートします。

package example;

import javax.xml.bind.annotation.*;

2. Customerクラスを宣言し、@XmlRootElement注釈を使用してルート要素にします。XMLアクセッサ・タイプにFIELDを設定します。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

3. Customerクラスのidプロパティを属性としてマップします。

@XmlAttribute
private Integer id;

このオブジェクトは例7-12のようになります。

例7-12 マップされたidプロパティが設定されたCustomerオブジェクト

package example;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlAttribute
private Integer id;

...
}

7.3.1.2 OXMメタデータ形式でのマッピングの定義

Oracle TopLinkのOXMメタデータ形式でマッピングを表す必要がある場合は、eclipselink-oxm.xmlファイルに定義されているXMLタグを使用して、適切な値を設定する必要があります。例7-13に例を示します。

例7-13 OXMメタデータ形式の属性としてのidのマッピング

...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-attribute java-attribute="id"/>
</java-attributes>
</java-type>
...

OXMメタデータ形式の詳細は、7.4項「XMLメタデータ表現を使用したJAXB注釈のオーバーライド」を参照してください。

7.3.2 テキスト・ノードへの値のマッピング

Oracle TopLinkでは、たとえば、単純なテキスト・ノード、単純な順序のテキスト・ノード、サブセットまたは位置別など、様々な種類のXMLテキスト・ノードにJavaオブジェクトから値を簡単にマップできます。これらのマッピングを次の例に示します。

- 単純なテキスト・ノードに対する値のマッピング

- 単純な順序でのテキスト・ノードへの値のマッピング

- サブ要素のテキスト・ノードに対する値のマッピング

- 位置によるテキスト・ノードへの値のマッピング

7.3.2.1 単純なテキスト・ノードに対する値のマッピング

JavaオブジェクトのJAXB注釈を使用して、またはTopLinkのOXMメタデータ形式でマッピングを表して、Javaオブジェクトから値をマップできます。

7.3.2.1.1 JAXB注釈を使用したマッピング

文字列値を受け入れる<phone-number>という要素が、関連するスキーマに定義されている場合は、@XmlValue注釈を使用して、<phone-number>ノードに文字列をマップできます。次を実行します:

1. オブジェクトを作成して、javax.xml.bind.annotation.*をインポートします。

package example;

import javax.xml.bind.annotation.*;

2. PhoneNumberクラスを宣言し、@XmlRootElement注釈を使用して、そのクラスをphone-numberという名前のルート要素にします。XMLアクセッサ・タイプにFIELDを設定します。

@XmlRootElement(name="phone-number")
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {

3. Customerクラスのnumberプロパティの前の行に@XmlValue注釈を挿入し、この値を属性としてマップします。

@XmlValue
private String number;

このオブジェクトは例7-14のようになります。

例7-14 マップされたnumberプロパティが指定されたPhoneNumberオブジェクト

package example;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="phone-number")
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
@XmlValue
private String number;

...
}

7.3.2.1.2 OXMメタデータ形式でのマッピングの定義

TopLinkのOXMメタデータ形式でマッピングを表す必要がある場合は、eclipselink-oxm.xmlファイルに定義されているXMLタグを使用して、適切な値を設定する必要があります。例7-15に例を示します。

例7-15 OXMメタデータ形式の属性としてのnumberのマッピング

...
<java-type name="PhoneNumber">
<xml-root-element name="phone-number"/>
<java-attributes>
<xml-value java-attribute="number"/>
</java-attributes>
</java-type>
...

7.3.2.2 単純な順序でのテキスト・ノードへの値のマッピング

JAXB注釈を使用して、またはTopLinkのOXMメタデータ形式でマッピングを表して、顧客の名と姓のような値の順序を個別の要素としてマップできます。次の手順では、顧客の名と姓の値をマップする方法を示しています。

7.3.2.2.1 JAXB注釈を使用したマッピング

関連するスキーマに次の要素が定義されていると仮定します。

- それ自身がcomplexTypeとして定義されている、タイプcustomer-typeの<"customer">

- 両方ともタイプstringの<"first-name">と<"last-name">という名前の順序要素。

@XmlElement注釈を使用すれば、顧客の名と姓の値を適切なXMLノードにマップできます。これを行うには:

1. オブジェクトを作成して、javax.xml.bind.annotation.*をインポートします。

package example;

import javax.xml.bind.annotation.*;

2. Customerクラスを宣言し、@XmlRootElement注釈を使用してルート要素にします。XMLアクセッサ・タイプにFIELDを設定します。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

3. firstnameおよびlastnameプロパティを定義して、@XmlElement注釈で注釈を付けます。name=引数を使用して、XML要素名をカスタマイズします(name=で名前を明示的に設定していないと、XML要素では、Java属性名が照合されます。たとえば、ここでは、<first-name>要素の組合せが、<firstName> </firstName>とXMLに指定されます)。

@XmlElement(name="first-name")
private String firstName;

@XmlElement(name="last-name")
private String lastName;

このオブジェクトは例7-16のようになります。

例7-16 単純な順序に対するCustomerオブジェクトの値のマッピング

package example;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name="first-name")
private String firstName;

@XmlElement(name="last-name")
private String lastName;

...
}

7.3.2.2.2 OXMメタデータ形式でのマッピングの定義

TopLinkのOXMメタデータ形式でマッピングを表す必要がある場合は、eclipselink-oxm.xmlファイルに定義されているXMLタグを使用して、適切な値を設定する必要があります。例7-17に例を示します。

例7-17 OXMメタデータ形式での順序属性のマッピング

...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="firstName" name="first-name"/>
<xml-element java-attribute="lastName" name="last-name"/>
</java-attributes>
</java-type>
...

7.3.2.3 サブ要素のテキスト・ノードに対する値のマッピング

JAXB注釈を使用して、またはTopLinkのOXMメタデータ形式でマッピングを表して、XML文書のサブ要素としてネストされているテキスト・ノードに、Javaオブジェクトから値をマップできます。たとえば、<customer>ルートの<personal-info>のサブ要素である<first-name>および<last-name>要素に値を設定する必要がある場合は、次の手順でマッピングを設定できます。

7.3.2.3.1 JAXB注釈を使用したマッピング

関連するスキーマに次の要素が定義されていると仮定します。

- それ自身がcomplexTypeとして定義されている、タイプcustomer-typeの<"customer">

- <personal-info>

- 両方ともタイプstringの<"first-name">と<"last-name">という名前の<personal-info>のサブ要素

JAXBの注釈を使用すれば、顧客の名と姓の値を適切なXMLサブ要素ノードにマップできます。この例では、単純な要素名のカスタマイズではなく、実際に新しいXML構造が導入されているので、TopLinkの@XmlPath注釈を使用しています。このマッピングを実現するには:

1. オブジェクトを作成して、javax.xml.bind.annotation.*およびorg.eclipse.persistence.oxm.annotations.*をインポートします。

package example;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

2. Customerクラスを宣言し、@XmlRootElement注釈を使用してルート要素にします。XMLアクセッサ・タイプにFIELDを設定します。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

3. firstNameおよびlastNameプロパティを定義します。

4. プロパティ宣言の直前の行に@XmlPath注釈を挿入して、XMLスキーマによって定義されたサブ要素にfirstNameおよびlastNameプロパティをマップします。各注釈に対して、適切なXPath述語を指定してマッピングを定義します。

@XmlPath("personal-info/first-name/text()")
private String firstName;

@XmlPath("personal-info/last-name/text()")
private String lastName;

このオブジェクトは例7-18のようになります。

例7-18 プロパティをサブ要素にマッピングするCustomerオブジェクト

package example;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlPath("personal-info/first-name/text()")
private String firstName;

@XmlPath("personal-info/last-name/text()")
private String lastName;

...
}

7.3.2.3.2 OXMメタデータ形式でのマッピングの定義

TopLinkのOXMメタデータ形式でマッピングを表す必要がある場合は、eclipselink-oxm.xmlファイルに定義されているXMLタグを使用して、適切な値を設定する必要があります。例7-19に例を示します。

例7-19 OXMメタデータ形式のサブ要素としての属性のマッピング

...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="firstName" xml-path="personal-info/first-name/text()"/>
<xml-element java-attribute="lastName" xml-path="personal-info/last-name/text()"/>
</java-attributes>
</java-type>
...

7.3.2.4 位置によるテキスト・ノードへの値のマッピング

複数のノードの名前が同じ場合には、XML文書内の位置を指定して、Javaオブジェクトから値をマップします。これを行うには、属性の名前ではなく、属性の位置に値をマップします。これは、JAXB注釈を使用するか、TopLinkのOXMメタデータ形式でマッピングを表すことによって行えます。次の例では、2つの<name>要素がXMLに含まれています。最初の名前は顧客の名を表し、2番名の名前は顧客の姓を表しています。

7.3.2.4.1 JAXB注釈を使用したマッピング

次の属性が定義されたXMLスキーマがあるとします。

- それ自身がcomplexTypeとして定義されている、タイプcustomer-typeの<customer>

- タイプStringの<name>

この例でも、JAXBの@XmlPath注釈を使用して、顧客の名と姓を適切な<name>要素にマップします。また、@XmlType(propOrder)注釈も使用して、要素が常に正しい位置に配置されるようにします。このマッピングを実現するには:

1. オブジェクトを作成して、javax.xml.bind.annotation.*およびorg.eclipse.persistence.oxm.annotations.XmlPathをインポートします。

package example;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

2. Customerクラスを宣言して、"firstName"引数の後に"lastName"引数が指定された@XmlType(propOrder)注釈を挿入します。@XmlRootElement注釈を挿入して、Customerをルート要素にし、XMLアクセッサ・タイプにFIELDを指定します。

@XmlRootElement
@XmlType(propOrder={"firstName", "lastName"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

3. タイプStringが指定されたプロパティfirstNameおよびlastNameを定義します。

4. 適切なXPath述語が指定された@XmlPathを挿入して、プロパティfirstNameおよびlastNameをXML文書の適切な位置にマップします。

@XmlPath("name[1]/text()")
private String firstName;

@XmlPath("name[2]/text()")
private String lastName;

述語"name[1]/text()"および"name[2]/text()"は、特定のプロパティがマップされる<name>要素を示しています。たとえば、"name[1]/text"はfirstNameプロパティを最初の<name>要素にマップします。

このオブジェクトは例7-20のようになります。

例7-20 位置により値をマップするCustomerオブジェクト

package example;

import javax.xml.bind.annotation.*;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlType(propOrder={"firstName", "lastName"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlPath("name[1]/text()")
private String firstName;

@XmlPath("name[2]/text()")
private String lastName;

...
}

XPath述語の使用方法の詳細は、7.5項「マッピング用のXPath述語の使用」を参照してください。

7.4 XMLメタデータ表現を使用したJAXB注釈のオーバーライド

TopLinkには、Java注釈の使用に加えて、JAXB注釈のかわりに使用したり、ソースのJAXB注釈をメタデータのXML表現で置換したりできるeclipselink-oxm.xmlという名前のXMLマッピング構成ファイルが用意されています。すべての標準JAXBマッピング機能を使用できるだけでなく、高度なマッピング・タイプとオプションも使用できます。

XMLのメタデータ表現は、次の場合に便利です。

- サード・パーティから入手したなどの理由でドメイン・モデルを変更できない場合。

- JAXBのAPIにコンパイル時の依存関係が存在しないようにする必要がある場合(Java SE 6より前のバージョンのJavaを使用している場合)。

- 複数のJAXBマッピングをドメイン・モデルに適用する必要がある場合(注釈では1つに制限されます)。

- 他のテクノロジからの多数の注釈がすでにオブジェクト・モデルに含まれているので、さらに追加するとクラスが読みにくくなる場合。

この項では、eclipselink-oxm.xmlを使用してJAXBの注釈をオーバーライドする方法を示します。

注意:

このマッピング・ファイルを使用すると多くの高度な機能が有効になりますが、他のJAXBの実装に移植できなくなる場合があります。

7.4.1 タスク1: XMLでの高度なマッピングの定義

まず、XMLマッピング・ファイルを更新して、eclipselink_oxm_2_3.xsdスキーマを公開します。例7-21は、マッピング・ファイルの<xml-bindings>要素を変更し、正しいネームスペースを指して、スキーマを利用する方法を示しています。各Javaパッケージには1つのマッピング・ファイルを指定できます。

例7-21 マッピング・ファイル内のXMLバインディング情報の更新

<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm  http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_3.xsd"
version="2.3">
</xml-bindings>

7.4.2 タスク2: JAXBContextの使用方法の構成

次に、オブジェクトのJAXBContextにマッピング・ファイルを渡します。

1. 次のコードを挿入して、外部化されたメタデータを指定します。

Map<String, Source> metadata = new HashMap<String,Source>();
metadata.put("example.order", new StreamSource("order-metadata.xml"));
metadata.put("example.customer", new StreamSource("customer-metadata.xml"));

2. JAXBContextに渡すプロパティ・オブジェクトを作成します。この例では、次のようになります。

Map<String,Object> properties = new HashMap<String,Object>();
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadata);

3. JAXBContextを作成します。この例では:

JAXBContext.newInstance("example.order:example.customer", aClassLoader, properties);

7.4.3 タスク3: JAXB実装としてのMOXyの指定

MOXyをJAXB実装として使用する必要があります。これを行うには、次を実行します:

1. jaxb.propertiesファイルをオープンして、次の行を追加します。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

2. ドメイン・クラスが格納されたパッケージにjaxb.propertiesファイルをコピーします。

7.5 マッピングに対するXPath述語の使用

この項では、TopLinkのMOXy APIでXPath述語を使用して、XML要素の名前を指定する式を定義する方法を説明します。XPath述語とは、オブジェクトからXMLへの特定のマッピングを定義する式のことです。前述の例で示したように、JAXBのデフォルトでは、Javaのフィールド名がXML要素名として使用されます。

この項には次のサブセクションがあります。

- 7.5.1項「XPath述語の理解」

- 7.5.2項「位置に基づくマッピング」

- 7.5.3項「属性値に基づくマッピング」

- 7.5.4項「セルフ・マッピング」

7.5.1 XPath述語の理解

前述のとおり、XPath述語とは、標準の注釈時にオブジェクトからXMLへの特定のマッピングを定義する式のことです。

十分ではありません。たとえば、XMLの次のスニペットは、2つの<node>サブ要素が指定された<data>要素を示しています。このマッピングをJavaオブジェクトに作成する場合は、各<node>サブ要素にXPath述語を指定する必要があります。たとえば、次のJavaでは、Node[2]と指定されています。

<java-attributes>
<xml-element java-attribute="node" xml-path="node[1]/ABC"/>
<xml-element java-attribute="node" xml-path="node[2]/DEF"/>
</java-attributes>

これは、次のXMLで2番目に出現するnode要素("DEF")と一致します。

<?xml version="1.0" encoding="UTF-8"?>
<data>
<node>ABC</node>
<node>DEF</node>
</data>

このように、XPath述語を使用すれば、異なる属性値に対して同じ属性名を使用できます。

7.5.2 位置に基づくマッピング

このマッピング方法は、7.3.2.4項「位置によるテキスト・ノードへの値のマッピング」に説明されています。

7.5.3 属性値に基づくマッピング

EclipseLink MOXy 2.3以降では、属性値に基づいてXML要素にマップすることもできます。この演習では、JPAエンティティに注釈を付けて、例7-22に示されているXML文書をレンダリングします。すべてのXML要素は名前付きノードですが、名前属性の値によって区別されていることに注意してください。

例7-22

<?xml version="1.0" encoding="UTF-8"?>
<node>
<node name="first-name">Bob</node>
<node name="last-name">Smith</node>
<node name="address">
<node name="street">123 A Street</node>
</node>
<node name="phone-number" type="work">555-1111</node>
<node name="phone-number" type="cell">555-2222</node>
</node>

このマッピングを実現するには、Name、AddressおよびPhoneNumberの3つのクラスを宣言し、element-name[@attribute-name='value']の形式でXPathを使用して、各Javaフィールドをマップする必要があります。

7.5.3.1 タスク1: Customerエンティティの作成

Customerクラス・エンティティを作成するには:

1. 次のコードを追加して、必要なJPAパッケージをインポートします。

import javax.xml.bind.annotation.*;

import org.eclipse.persistence.oxm.annotations.XmlPath;

2. Customerクラスを宣言し、@XmlRootElement注釈を使用してルート要素にします。XMLアクセッサ・タイプにFIELDを設定します。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

3. Customerクラスに対して、次のプロパティをローカルに宣言します。

- firstName (文字列型)

- lastName (文字列)

- Address (住所)

@XmlPath(element-name[@attribute-name='value'])をプロパティ宣言の前に記述することにより、各プロパティに対してXPath述語を設定します。たとえば、firstNameの場合は、次の文でXPath述語を設定します。

@XmlPath("node[@name='first-name']/text()")

4. また、Customerクラスに対してphoneNumberプロパティをList<PhoneNumber>タイプでローカルに宣言し、値new ArrayList<PhoneNumber>()をそれに割り当てます。

Customerクラスは例7-23のスニペットのようになります。

例7-23 属性値にマッピングされているCustomerオブジェクト

package example;

import javax.xml.bind.annotation.*;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="node")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

@XmlPath("node[@name='first-name']/text()")
private String firstName;

@XmlPath("node[@name='last-name']/text()")
private String lastName;

@XmlPath("node[@name='address']")
private Address address;

@XmlPath("node[@name='phone-number']")
private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();

...
}

7.5.3.2 タスク2: Addressエンティティの作成

Addressクラスを作成するには、次を実行します:

1. 次のコードを追加して、必要なJPAパッケージをインポートします。

import javax.xml.bind.annotation.*;

import org.eclipse.persistence.oxm.annotations.XmlPath;

2. Addressクラスを宣言して、XMLアクセッサ・タイプにFIELDを設定します。

@XmlAccessorType(XmlAccessType.FIELD)
public class Address {

AddressクラスがXML文書のルート要素ではないので、このインスタンスには、前述のタスクのように@XmlRootElement注釈は必要ありません。

3. StringプロパティstreetをAddressクラスに対してローカルに宣言します。注釈@XmlPath("node[@name='street']/text()")をプロパティ宣言の前に記述して、XPath述語を設定します。

Addressクラスは例7-24のようになります。

例7-24 属性値に対するAddressオブジェクトのマッピング

package example;

import javax.xml.bind.annotation.*;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlAccessorType(XmlAccessType.FIELD)
public class Address {

@XmlPath("node[@name='street']/text()")
private String street;

...
}

7.5.3.3 タスク3: PhoneNumberエンティティの作成

PhoneNumberエンティティを作成するには:

1. 次のコードを追加して、必要なJPAパッケージをインポートします。

import javax.xml.bind.annotation.*;

import org.eclipse.persistence.oxm.annotations.XmlPath;

2. PhoneNumberクラスを宣言し、@XmlRootElement注釈を使用して、クラスをルート要素にします。XMLアクセッサ・タイプにFIELDを設定します。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

3. typeおよびstringプロパティを作成し、@XmlAttribute注釈を使用して、PhoneNumberルート要素の属性としてマッピングを定義します。

@XmlAttribute
private String type;

@XmlValue
private String number;

PhoneNumberオブジェクトは例7-25のようになります。

例7-25 属性値に対するPhoneNumberオブジェクトのマッピング

package example;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {

@XmlAttribute
private String type;

@XmlValue
private String number;

...
}

7.5.4 セルフ・マッピング

セルフ・マッピングは、ターゲット・オブジェクトからのデータがソース・オブジェクトのXML要素内に表示されるようにターゲット・オブジェクトのXPathを"."(ドット)に設定した場合に、1対1のマッピングで発生します。この演習では、7.5.3項「属性値に基づくマッピング」の例を使用して、Addressの情報が、自分の要素にラップされずにcustomer要素に直接表示されるようにマップします。

セルフ・マッピングを作成するには:

1. 7.5.3.1項「タスク1: Customerエンティティの作成」のタスク1と2を繰り返します。

2. Customerクラスに対して、次のプロパティをローカルに宣言します。

- firstName (文字列型)

- lastName (文字列)

- Address (住所)

3. @XmlPath(element-name[@attribute-name='value'])をプロパティ宣言の前に記述することにより、firstNameおよびlastNameプロパティに対してXmlPath注釈を設定します。たとえば、firstNameの場合は、次の文でXPath述語を設定します。

@XmlPath("node[@name='first-name']/text()")

4. addressプロパティの@XmlPathに"."(ドット)を設定します。

@XmlPath(".")
private Address address;

5. また、Customerクラスに対してphoneNumberプロパティをList<PhoneNumber>タイプでローカルに宣言し、値new ArrayList<PhoneNumber>()をそれに割り当てます。

Customerエンティティに対してレンダリングされるXMLは例7-26のようになります。

例7-26 セルフ・マッピングされたAddress要素が指定されたXMLノード

<?xml version="1.0" encoding="UTF-8"?>
<node>
<node name="first-name">Bob</node>
<node name="last-name">Smith</node>
<node name="street">123 A Street</node>
<node name="phone-number" type="work">555-1111</node>
<node name="phone-number" type="cell">555-2222</node>
</node>

7.6 動的JAXB/MOXyの使用

動的JAXB/MOXyでは、様々なメタデータ・ソースからJAXBContextをブートストラップでき、コンパイルされたドメイン・クラスがなくても、使い慣れたJAXBのAPIを使用してデータのマーシャルおよびアンマーシャルを行えます。以前に生成されたJavaソース・コードを更新および再コンパイルしなくてもメタデータを更新できるようになったので、これは静的JAXBに対する拡張機能になります。

動的JAXB/MOXyのエンティティを使用すると、次のような利点があります。

- 実際のJavaクラス(たとえば、Customer.class、Address.class)を使用するかわりに、ドメイン・オブジェクトがDynamicEntityのサブクラスになります。

- 動的エンティティには、データを操作するためのget(propertyName)/set(propertyName propertyValue)という簡単なAPIが用意されています。

- 動的エンティティには、メタデータの解析時にメモリー内に生成されるDynamicTypeが関連付けられています。

次のタスクで、動的JAXBの使用方法を示します。

- タスク1: XMLスキーマからの動的JAXBContextのブートストラップ

- タスク2: 動的エンティティの作成とXMLへのマーシャル

- タスク3: XMLからの動的エンティティのアンマーシャル

7.6.1 タスク1: XMLスキーマからの動的JAXBContextのブートストラップ

この例は、XMLスキーマから動的JAXBContextをブートストラップする方法を示しています。

7.6.1.1 XMLスキーマからのブートストラップ

DynamicJAXBContextFactoryを使用して、動的JAXBContextを作成します。例7-27は、createContextFromXSD()を使用してDynamicJAXBContextをcustomer.xsdスキーマ(例7-28)からブートストラップしています。

例7-27 入力ストリームの指定およびDynamicJAXBContextの作成

import java.io.FileInputStream;

import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;

public class Demo {

public static void main(String[] args) throws Exception {
FileInputStream xsdInputStream = new FileInputStream("src/example/customer.xsd");
DynamicJAXBContext jaxbContext =
DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, null, null, null);

最初のパラメータはXMLスキーマ自身を表し、java.io.InputStream、org.w3c.dom.Node、javax.xml.transform.Sourceのいずれかの形式である必要があります。

7.6.1.2 XMLスキーマ

例7-28は、ブートストラップする対象の動的JAXBContextのメタデータを表すcustomer.xsdスキーマを示しています。

例7-28 サンプルXMLスキーマ文書

<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.org"
targetNamespace="http://www.example.org"
elementFormDefault="qualified">

<xsd:complexType name="address">
<xsd:sequence>
<xsd:element name="street" type="xsd:string" minOccurs="0"/>
<xsd:element name="city" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>

<xsd:element name="customer">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string" minOccurs="0"/>
<xsd:element name="address" type="address" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>

7.6.1.3 スキーマのインポート/インクルードの処理

他のスキーマのインポートが格納されたXMLスキーマからDynamicJAXBContextをブートストラップするには、org.xml.sax.EntityResolverを構成し、インポートされたスキーマの場所を解決して、EntityResolverをDynamicJAXBContextFactoryに渡す必要があります。

次の例は、customer.xsd (例7-29)とaddress.xsd (例7-30)の2つのスキーマ文書を示しています。次の文を使用して、customer.xsdがaddress.xsdをインポートしていることがわかります。

<xsd:import namespace="http://www.example.org/address" schemaLocation="address.xsd"/>

例7-29 customer.xsd

<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:add="http://www.example.org/address"
xmlns="http://www.example.org/customer"
targetNamespace="http://www.example.org/customer"
elementFormDefault="qualified">

<xsd:import namespace="http://www.example.org/address" schemaLocation="address.xsd"/>

<xsd:element name="customer">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string" minOccurs="0"/>
<xsd:element name="address" type="add:address" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>

例7-30 address.xsd

<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.org/address"
targetNamespace="http://www.example.org/address"
elementFormDefault="qualified">

<xsd:complexType name="address">
<xs:sequence>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
</xs:sequence>
</xsd:complexType>

</xsd:schema>

7.6.1.4 EntityResolverを実装して渡す方法

DynamicJAXBContextをcustomer.xsdスキーマからブートストラップする場合は、エンティティ・リゾルバを渡す必要があります。次を実行します:

1. インポートされたスキーマの場所を解決するには、例7-31に示されたコードを指定して、entityResolverを実装する必要があります。

例7-31 EntityResolverの実装

class MyEntityResolver implements EntityResolver {

public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
// Imported schemas are located in ext\appdata\xsd\

// Grab only the filename part from the full path
String filename = new File(systemId).getName();

// Now prepend the correct path
String correctedId = "ext/appdata/xsd/" + filename;

InputSource is = new InputSource(ClassLoader.getSystemResourceAsStream(correctedId));
is.setSystemId(correctedId);

return is;
}

}

2. DynamicJAXBContextを実装した後、例7-32に示すようにEntityResolverを渡します。

例7-32 EntityResolverを渡す方法

FileInputStream xsdInputStream = new FileInputStream("src/example/customer.xsd");
DynamicJAXBContext jaxbContext =
DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, new MyEntityResolver(), null, null);

7.6.1.5 エラー処理

別のスキーマをインポートする際に、次の例外が表示される場合があります。

Internal Exception: org.xml.sax.SAXParseException: schema_reference.4: Failed to read schemadocument '<imported-schema-name>', because 1) could not find the document; 2) the document couldnot be read; 3) the root element of the document is not <xsd:schema>.

この例外を回避するには、noCorrectnessCheck Javaプロパティを設定して、XJCのスキーマ正当性チェックを無効にします。このプロパティは、次の2つのいずれかの方法で設定できます。

- コード内に次の行を追加します。

System.setProperty("com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.noCorrectnessCheck", "true")

- コマンド・ラインから次のコマンドを使用します。

-Dcom.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.noCorrectnessCheck=true

7.6.1.6 ClassLoaderの指定

アプリケーションの現在のクラス・ローダーをclassLoaderパラメータとして使用します。このパラメータでは、新しいDynamicTypesが生成される前に、指定したクラスが存在することが確認されます。ほとんどの場合、このパラメータにnullを渡して、かわりにThread.currentThread().getContextClassLoader()を使用できます。

7.6.2 タスク2: 動的エンティティの作成とXMLへのマーシャル

この例は、動的エンティティを作成してXMLにマーシャルする方法を示しています。

7.6.2.1 動的エンティティの作成

DynamicJAXBContextを使用して、DynamicEntityのインスタンスを作成します。エンティティとプロパティ名は、静的JAXBを使用していれば生成されたであろうクラスとプロパティ名(この場合は、customerとaddress)に対応しています。

例7-33 動的エンティティの作成

DynamicEntity customer = jaxbContext.newDynamicEntity("org.example.Customer");
customer.set("name", "Jane Doe");

DynamicEntity address = jaxbContext.newDynamicEntity("org.example.Address");
address.set("street", "1 Any Street").set("city", "Any Town");
customer.set("address", address);

7.6.2.2 XMLへの動的エンティティのマーシャリング

DynamicJAXBContextから入手したマーシャラは、標準のマーシャラで、DynamicEntityのインスタンスをマーシャルするために通常どおり使用できます。

例7-34 標準の動的JAXBマーシャラ

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.marshal(customer, System.out);

例7-35は結果のXML文書を示しています。

例7-35 <address>要素とその属性が表示された更新済のXML文書

<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns="www.example.org">
<name>Jane Doe</name>
<address>
<street>1 Any Street</street>
<city>Any Town</city>
</address>
</customer>

7.6.3 タスク3: XMLからの動的エンティティのアンマーシャル

この例では、「タスク2: 動的エンティティの作成とXMLへのマーシャル」で作成した動的エンティティをXMLからアンマーシャルする方法を示します。参照されているXMLは例7-35に示されています。

7.6.3.1 XMLからの動的エンティティのアンマーシャル

DynamicJAXBContextから入手したアンマーシャラは、標準のアンマーシャラで、DynamicEntityのインスタンスをアンマーシャルするために通常どおり使用できます。

例7-36 標準の動的JAXBアンマーシャラ

FileInputStream xmlInputStream = new FileInputStream("src/example/dynamic/customer.xml");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DynamicEntity customer = (DynamicEntity) unmarshaller.unmarshal(xmlInputStream);

7.6.3.2 動的エンティティからのデータの取得

次に、動的エンティティのどのデータを取得するかを指定します。System.out.println()を使用して、この値を指定し、エンティティ名で渡します。DynamicEntityには、たとえば、getName()のかわりにget("name")のようなプロパティに基づいたデータ・アクセスが用意されています。

System.out.println(customer.<String>get("name"));

7.6.3.3 DynamicTypeを使用した、動的エンティティのイントロスペクション

DynamicEntityのインスタンスには、例7-37に示されているようにDynamicEntityをイントロスペクトするために使用できる、対応するDynamicTypeがあります。

例7-37

DynamicType addressType = jaxbContext.getDynamicType("org.example.Address"); DynamicEntity address = customer.<DynamicEntity>get("address");for(String propertyName: addressType.getPropertiesNames()) {    System.out.println(address.get(propertyName));}

8 コンテナ外部のTopLink JPAのテスト

TopLinkでは、永続性ユニットのJARを使用して、コンテナの外のアプリケーション(たとえば、Java Platform, Standard Edition (Java SE)のアプリケーション)をテストできます。

この章では、次の項目について説明します。

- 8.1項「JPAデプロイメントの理解」

- 8.2項「persistence.xmlファイルの構成」

- 8.3項「プロパティ・マップの使用」

- 8.4項「その他の参考資料」

8.1 JPAデプロイメントの理解

コンテナの外部にデプロイする場合は、javax.persistence.PersistenceクラスのcreateEntityManagerFactoryメソッドを使用して、エンティティ・マネージャ・ファクトリを作成します。このメソッドは、プロパティのMapおよび永続性ユニットの名前を受け入れます。このメソッドに渡すプロパティは、persistence.xmlファイル指定されているプロパティと組み合されます。追加のプロパティの場合もあれば、persistence.xmlファイルに以前に指定したプロパティの値を上書きする場合もあります。

ヒント:

これは、コマンドラインなどのプログラム入力から取得したプロパティを設定するのに便利な方法です。

8.1.1 EntityManagerの使用

EntityManagerは、エンティティBeanを永続化したり、データベースからロードしたりするためのアクセス・ポイントです。通常は、JPAコンテナで、データ・ソースとのやりとりを管理します。ただし、JPA永続性ユニットに対してJTAデータ・ソースを使用している場合は、Java EEコンテナのデータ・ソースからJDBC接続にアクセスできます。管理対象のデータ・ソースを使用できないので、persistence.xmlファイルに接続情報を含める必要があります。

Oracle TopLinkでは、EntityManagerに対するEclipseLinkの拡張機能にもアクセスできます。

8.2 persistence.xmlファイルの構成

persistence.xmlファイルは、Java Persistence API (JPA)を使用した永続性のデプロイメント・ディスクリプタ・ファイルです。ここには、永続性ユニットを指定し、管理対象永続性クラス、オブジェクト/リレーション・マッピング、およびデータベース接続の詳細を宣言します。

8.2.1 主なタスク

この項には、次の項目が含まれます。

- タスク1: persistence.xmlファイルの使用

- タスク2: EntityManagerFactoryのインスタンス化

8.2.1.1 タスク1: persistence.xmlファイルの使用

例8-1に、JavaSE構成(つまり、コンテナの外部)用のpersistence.xmlファイルを示します。

例8-1 JavaSE構成を指定するpersistence.xmlファイル

<persistence 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 persistence_1_0.xsd" version="1.0">
<persistence-unit name="my-app" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="javax.persistence.jdbc.user" value="scott"/>
<property name="javax.persistence.jdbc.password" value="tiger"/>
</properties>
</persistence-unit>
</persistence>

8.2.1.2 タスク2: EntityManagerFactoryのインスタンス化

EntityManagerFactoryを使用すれば、データベースのEntityManagerインスタンスを効率的に作成できます。次の方法を使用して、(例8-1に示す)アプリケーションのEntityManagerFactoryをインスタンス化できます。

Persistence.createEntityManagerFactory("my-app");

8.3 プロパティ・マップの使用

プロパティ・マップを使用して、デフォルトの永続性プロパティをオーバーライドできます。

8.3.1 主なタスク

この項の手順は次のとおりです。

- タスク1: persistence.xmlファイルの構成

- タスク2: ブートストラップAPIの構成

- タスク3: EntityManagerFactoryのインスタンス化

8.3.1.1 タスク1: persistence.xmlファイルの構成

例8-2に、コンテナ・デプロイメントを使用するpersistence.xmlファイルを示します。

例8-2 JavaSE構成を指定するpersistence.xmlファイル

<persistence 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 persistence_1_0.xsd" version="1.0">
<persistence-unit name="employee" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/MyDS</non-jta-data-source>
</persistence-unit>
</persistence>

注意:

コンテナの外でテストする際に、データ・ソースは使用できません。

8.3.1.2 タスク2: ブートストラップAPIの構成

例8-2に示されている永続性ユニットをコンテナの外でテストするには、JavaSEのブートストラップAPIを使用する必要があります。例8-3に、このブートストラップを示すサンプル・コードを示します。

例8-3 サンプル構成

import static org.eclipse.persistence.config.PersistenceUnitProperties.*;

...

Map properties = new HashMap();

// Ensure RESOURCE_LOCAL transactions is used.
properties.put(TRANSACTION_TYPE,
PersistenceUnitTransactionType.RESOURCE_LOCAL.name());

// Configure the internal connection pool
properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver");
properties.put(JDBC_URL, "jdbc:oracle:thin:@localhost:1521:ORCL");
properties.put(JDBC_USER, "scott");
properties.put(JDBC_PASSWORD, "tiger");

// Configure logging. FINE ensures all SQL is shown
properties.put(LOGGING_LEVEL, "FINE");
properties.put(LOGGING_TIMESTAMP, "false");
properties.put(LOGGING_THREAD, "false");
properties.put(LOGGING_SESSION, "false");

// Ensure that no server-platform is configured
properties.put(TARGET_SERVER, TargetServer.None);

8.3.1.3 タスク3: EntityManagerFactoryのインスタンス化

EntityManagerFactoryを使用すれば、データベースのEntityManagerインスタンスを効率的に作成できます。次の方法を使用して、(例8-3に示す)アプリケーションのEntityManagerFactoryをインスタンス化できます。

Persistence.
createEntityManagerFactory("unitName", "Properties");

8.4 その他の参考資料

JPAデプロイメントの詳細は、JPA仕様の次の項(http://jcp.org/en/jsr/detail?id=317)を参照してください。

- 7.2項「Bootstrapping in Java SE Environments」

- 第7章「Container and Provider Contracts for Deployment and Bootstrapping」

8.4.1 Javadoc

詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』の次のAPIを参照してください。

- PersistenceUnitPropertiesクラス

- EntityManagerFactoryインタフェース

- JpaEntityManagerインタフェース

9 パフォーマンスの向上

この章では、TopLinkのパフォーマンス機能およびTopLinkが有効なアプリケーションの監視方法および最適化方法を説明します。

この章には次の項が含まれます:

- 9.1項「パフォーマンス機能」

- 9.2項「TopLinkが有効なアプリケーションの監視および最適化

9.1 パフォーマンス機能

Toplinkには、多くのパフォーマンス機能が含まれているので、業界で最高のパフォーマンスと最高のスケーラビリティを備えたJPA実装を提供できます。次の機能が含まれています。

- オブジェクト・キャッシング

- 問合せ

- マッピング

- トランザクション

- データベース

- ツール

9.1.1 オブジェクト・キャッシング

TopLinkキャッシュは、クラスと主キーの値に基づいて最近読み取られたり書き込まれたオブジェクトが格納される、インメモリー・リポジトリです。キャッシュは、最近の読取りまたは書込みオブジェクトを保持し、メモリー内でそれらにアクセスしてデータベースへのアクセスを最小限にすることで、パフォーマンスの向上を助けます。

キャッシングでは、次のことを行えます。

- キャッシュの無効化と呼ばれるプロセスで、キャッシュの存続期間および時間を設定できます。

- キャッシュ・タイプ(Weak、Soft、SoftCache、HardCache、Full)をエンティティごとに構成できます。

- エンティティごとにキャッシュ・サイズを構成できます。

- クラスタ化されたキャッシュを調整できます。

9.1.1.1 キャッシング注釈

TopLinkには、次のエンティティ・キャッシング注釈が定義されています。

- @Cache

- @TimeOfDay

- @ExistenceChecking

TopLinkには、TopLinkキャッシュを構成するために指定できる永続性ユニットのプロパティも多数用意されています(http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#How_to_Use_the_Persistence_Unit_Properties_for_CachingにあるEclipseLinkオンライン・ドキュメントの『How to Use the Persistence Unit Properties for Caching』を参照)。これらのプロパティを注釈のかわりに使用したり、注釈を補完したりできる場合があります。

9.1.1.2 @Cache注釈の使用

TopLinkでは、パフォーマンスの向上およびオブジェクト・アイデンティティの保持のために、アイデンティティ・マップを使用してオブジェクトがキャッシュされます。エンティティ・クラスで@Cache注釈を使用すれば、キャッシュおよびその動作を制御できます。例9-1に、この注釈の実装方法を示します。

例9-1 @Cache注釈の使用

@Entity
@Table(name="EMPLOYEE")
@Cache (
type=CacheType.WEAK,
isolated=false,
expiry=600000,
alwaysRefresh=true,
disableHits=true,
coordinationType=INVALIDATE_CHANGED_OBJECTS
)
public class Employee implements Serializable {
...
}

オブジェクト・キャッシングおよび@Cache注釈の使用の詳細は、次のEclipseLinkオンライン・ドキュメントの『Using EclipseLink JPA Extensions for Entity Caching』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Entity_Caching

9.1.2 問合せ

問合せの範囲、返されるデータ量、およびデータが返される方法はすべて、TopLinkが有効になっているアプリケーションのパフォーマンスに影響を与える可能性があります。Toplinkの問合せメカニズムでは、次の機能を提供して問合せパフォーマンスを向上しています。

- 読取り専用問合せ

- 結合フェッチ

- バッチ読取り

- フェッチ・サイズ

- ページ区切り

- キャッシュの使用方法

この項では、これらの機能により、どのようにパフォーマンスが向上するかを説明します。

9.1.2.1 読取り専用問合せ

TopLinkでは、eclipselink.read-onlyヒント、QueryHint (@QueryHint)を使用して、読取り専用の結果を問合せから取得します。リクエストされたエンティティ・タイプが共有キャッシュにストアされるような非トランザクションの読取り操作の場合は、デタッチされたコピーではなく、共有インスタンスが返されるようにリクエストできます。

読取り専用問合せの詳細は、次の読取り専用ヒントのドキュメントを参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Read_Only

9.1.2.2 結合フェッチ

結合フェッチでは、ソース・オブジェクトと同じ問合せにある関連オブジェクトの結合および読取りを有効にすることにより、パフォーマンスを向上します。例9-2に示すように、@JoinFetch注釈を使用して、結合フェッチを有効にします。この例では、EmployeeフィールドmanagedEmployeesを@JoinFetch注釈で指定する方法を示しています。

例9-2 結合フェッチの有効化

@Entity
public class Employee implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="owner")
@JoinFetch(value=OUTER)
public Collection<Employee> getManagedEmployees() {
return managedEmployees;
}
...
}

結合フェッチの詳細は、次のEclipseLinkオンライン・ドキュメントの『How to Use the @JoinFetch Annotation』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#How_to_Use_the_.40JoinFetch_Annotation

9.1.2.3 バッチ読取り

eclipselink.batchヒントは、TopLinkにバッチ処理情報を提供します。これにより、関連するオブジェクトに対する後続の問合せがバッチ内で最適化されるため、オブジェクトを1つずつ取得したり、大規模な1つの結合読取りで取得したりすることを回避できます。バッチ読取りでは、重複データの読取りが回避されるので、結合よりも効率的です。バッチ処理は、SELECT句にオブジェクトが1つしかない問合せに対してのみ実行できます。

9.1.2.4 フェッチ・サイズ

多数のオブジェクトを返す大規模な問合せがある場合は、選択条件を満たすために必要なデータベースのヒット数を減らすことにより、パフォーマンスを向上できます。これを行うには、eclipselink.jdbc.fetch-sizeヒントを使用します。このヒントには、より多くの行が必要になる場合(JDBCドライバのサポート・レベルに従って)に、データベースからフェッチする行数を指定します。ほとんどのJDBCドライバのデフォルト・フェッチ・サイズは10になっています。そのため、1000個のオブジェクトを読み取る場合、フェッチ・サイズを256に増やすと、問合せ結果のフェッチに要する時間が大幅に短縮される場合があります。最適なフェッチ・サイズが常に明白であるとはかぎりません。通常は、予想される総結果サイズの半分または4分の1がフェッチ・サイズとして最適です。結果セットのサイズが不確かな場合に、誤ってフェッチ・サイズの設定を大きく、または小さくしすぎると、パフォーマンスが低下する可能性がありますので、注意してください。

9.1.2.5 ページ区切り

ページング処理が遅いと、アプリケーションの負荷が大幅に高くなる場合があります。ただし、TopLinkには次のようなページング結果が向上する様々な解決策が用意されています。

- 問合せの実行時に最初に取得する行数および最大行数を構成できます。

- 基準と一致するすべてのID値に対してデータベースで問合せを実行してから、ID値を使用して特定のセットを取得できます。

- 問合せヒントを使用して、ScrollableCursorオブジェクトを問合せから返すようにTopLinkを構成できます。これにより、問合せの結果セットにデータベース・カーソルが返されるので、クライアントでページごとに結果をスクロールできるようになります。

ページング・パフォーマンスの向上の詳細は、次のEclipseLinkオンライン・ドキュメントの『How to use EclipseLink Pagination』を参照してください。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination#How_to_use_EclipseLink_Pagination

9.1.2.6 キャッシュの使用方法

TopLinkでは、永続性ユニット全体を範囲とする共有キャッシュ・メカニズムを使用しています。特定の永続性コンテキストで操作が完了すると、結果が共有キャッシュに再びマージされて、他の永続性コンテキストが使用できるようになります。これは、エンティティ・マネージャおよび永続性コンテキストがJava SEまたはJava EEで作成されているかどうかに関係なく行われます。エンティティ・マネージャを使用して永続化または削除されたエンティティでは、常にキャッシュとの整合性が保たれます。

eclipselink.cache-usageヒントを使用すれば、問合せとTopLinkキャッシュとの相互作用の方法を指定できます。詳細は、次のEclipseLinkオンライン・ドキュメントの『Cache Usage』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Cache_Usage

9.1.3 マッピング

マッピング・パフォーマンスは次の機能で拡張されています。

- インダイレクション(遅延ロード)

- 読取り専用オブジェクト

- ウィービング

この項では、これらの機能を説明します。

9.1.3.1インダイレクション(遅延ロード)

デフォルトでは、永続オブジェクトが取得される際に、そのオブジェクトが参照する従属オブジェクトがすべて取得されます。リレーションシップ・マッピングによってマップされた属性に対してインダイレクション(遅延ロード、遅延読取りおよびジャストインタイム読取りとも呼びます)を構成すると、参照オブジェクトのプレースホルダとしてインダイレクション・オブジェクトが使用されます。その属性にアクセスするまで、従属オブジェクトの読取りは遅延されます。その結果、アプリケーションにとって重要なのは取得されたオブジェクトの内容のみであり、関連オブジェクトの内容は重要でないという場合は特に、パフォーマンスが大幅に向上します。

TopLinkは、Value Holderインダイレクション、透過インダイレクト・コンテナ・インダイレクション、およびプロキシ・インダイレクションなど、様々なタイプのインダイレクションをサポートします。

9.1.3.2 読取り専用オブジェクト

クラスを読取り専用に宣言すると、そのクラスのクローンの作成もマージも行われないので、パフォーマンスが大幅に向上します。addReadOnlyClass()を使用すれば、作業ユニットのコンテキスト内でクラスを読取り専用として宣言できます。

- 単一の作業ユニットに対して読取り専用クラスを構成するには、そのクラスをaddReadOnlyClass()の引数として指定します。

myUnitofWork.addReadOnlyClass(B.class);

- 複数のクラスを読取り専用に構成するには、それらのクラスをベクトルに追加して、そのベクトルをaddReadOnlyClass()の引数として指定します。

myUnitOfWork.addReadOnlyClasses(myVectorOfClasses);

読取り専用オブジェクトを使用してパフォーマンスを向上する方法の詳細は、次のEclipseLinkオンライン・ドキュメントの『Declaring Read-Only Classes』を参照してください。

http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#Declaring_Read-Only_Classes

9.1.3.3 ウィービング

ウィービングは、コンパイル済のJavaクラスのバイトコードを操作する方法です。TopLink JPA永続性プロバイダでは、ウィービングを使用して、遅延ロード、変更追跡、フェッチ・グループ、内部最適化などに対して、JPAエンティティとPlain Old Java Object (POJO)クラスの両方を拡張します。ウィービングは、実行時の動的実行、エンティティのロード時の実行、エンティティの.classファイルの後処理によるコンパイル時の静的実行のいずれかで実行できます。TopLinkのデフォルトでは、可能な場合は常に動的ウィービングが使用されます。これは、TopLinkエージェントの構成時に、Java EE 5/6アプリケーション・サーバー内およびJava SEに含まれています。動的ウィービングは構成しやすく、プロジェクトのビルド・プロセスを変更する必要がないので、動的ウィービングをお薦めします。

ウィービングを使用してアプリケーションのパフォーマンスを向上する方法の詳細は、次のEclipseLinkオンライン・ドキュメントの『Weaving』を参照してください。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving

9.1.4 トランザクション

データ・トランザクション時のパフォーマンスを最適化するには、変更追跡を使用します。変更追跡では、トランザクション中に発生した変更をTopLinkが検出する方法をチューニングできます。エンティティ・タイプが異なると、アクセス・パターンも設定も異なるので、エンティティ・タイプの使用パターンおよびデータ変更パターンに基づいて方式を選択します。

例9-3に示すように、@ChangeTracking注釈を使用して、変更追跡を有効にします。

例9-3 変更追跡の有効化

@Entity
@Table(name="EMPLOYEE")
@ChangeTracking(OBJECT) (
public class Employee implements Serializable {
...
}

変更追跡の詳細は、次のEclipseLinkオンライン・ドキュメントの『Using EclipseLink JPA Extensions for Tracking Changes』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Tracking_Changes

9.1.5 データベース

TopLinkのデータベース・パフォーマンス機能には、次のようなものがあります。

- 接続プーリング

- パラメータ化されたSQLとSQL文のキャッシュ

- バッチ書込み

この項では、これらの機能を説明します。

9.1.5.1 接続プーリング

データ・ソースへの接続の確立には時間がかかるため、接続プールにある接続を再使用すれば、パフォーマンスを向上できます。TopLinkは、接続プールを使用して、サーバーおよびクライアント・セッションで使用される接続を管理および共有します。この機能により、必要な接続数が減り、アプリケーションで多くのクライアントをサポートできるようになります。

デフォルトでは、TopLinkセッションは内部接続プールを使用します。これらのプールでは、表示専用でデータの変更が頻繁ではないデータを読み取るアプリケーション用の読取り接続の作成を最適化できます。また、ワークベンチを使用して、デフォルト(書込み)および読取りの接続プールを構成したり、オブジェクト・アイデンティティまたは他の目的のために追加の接続プールを作成することもできます。

内部接続プールに加えて、次のいずれかのタイプの接続プールを使用するようにTopLinkを構成することもできます。

- 外部接続プール。外部トランザクション・コントローラ(JTA)と統合するには、このタイプの接続プールを使用する必要があります。

- デフォルト(書込み)および読取り接続プール。

- シーケンス接続プール。表順序付け(つまり、非ネイティブ順序付け)が必要なアプリケーションで、外部トランザクション・コントローラを使用している場合には、これらのタイプのプールを使用します。アプリケーション固有の接続プール。TopLinkの内部接続プールをセッションで使用している場合は、アプリケーションの目的に従って、これらの接続プールを作成して使用できます。

TopLinkで接続プールを使用する方法の詳細は、EclipseLinkオンライン・ドキュメントの次のトピックを参照してください。

- Connection Pools
http://wiki.eclipse.org/Introduction_to_Data_Access_%28ELUG%29#Connection_Pools

- Introduction to the Internal Connection Pool Creation
http://wiki.eclipse.org/Creating_an_Internal_Connection_Pool_%28ELUG%29#Introduction_to_the_Internal_Connection_Pool_Creation

9.1.5.2 パラメータ化されたSQLとSQL文のキャッシュ

パラメータ化されたSQLを使用すれば、SQL問合せの全体の長さが、JDBCドライバまたはデータベース・サーバーで決められた文の長さ制限を超えることを防げます。パラメータ化されたSQLをプリコンパイル文のキャッシュとともに使用すると、コール頻度の高い問合せのSQLがデータベースのSQLエンジンによって解析およびプリコンパイルされる回数が減少し、パフォーマンスが向上します。

デフォルトでは、TopLinkはパラメータ使用のSQLは有効にしますが、プリコンパイルされたSQL文のキャッシュは有効にしません。内部接続プールの使用時はTopLinkで、外部接続プールの使用時はデータ・ソースで、文のキャッシュを有効にし、アプリケーションに適した文のキャッシュ・サイズを指定する必要があります。

パラメータ化されたSQLを有効にするには、ドメイン・クラスと同じパスにあるpersistence.xmlファイルに次の行を追加します。

<property name="eclipselink.jdbc.bind-parameters" value="true"/>

パラメータ化されたSQLを無効にするには、value=をfalseに変更します。

パラメータ化されたSQLおよびSQL文のキャッシュの詳細は、次のEclipseLinkオンライン・ドキュメントの『How to Use Parameterized SQL (Parameter Binding) and Prepared Statement Caching for Optimization』を参照してください。

http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#How_to_Use_Parameterized_SQL_.28Parameter_Binding.29_and_Prepared_Statement_Caching_for_Optimization

9.1.5.3 バッチ書込み

バッチ書込みは、複数の書込み操作があるトランザクションの最適化に役立ちます。バッチ書込みは、TopLinkのJDBC拡張機能のbatch-writingを使用して有効にします。デプロイ時に、次のパラメータのいずれかを、セッションのこのプロパティに設定してください。

- JDBC: JDBCのバッチ書込みを使用します。

- Buffered: JDBCのバッチ書込みもネイティブ・プラットフォームのバッチ書込みも使用しません。

- Oracle-JDBC: JDBCのバッチ書込みとOracleネイティブ・プラットフォームのバッチ書込みの両方を使用し、プロパティ・マップでOracleJDBCを使用します。

- None: バッチ書込みを無効にします。

バッチ書込みの詳細は、次のEclipseLinkオンライン・ドキュメントの『How to Use EclipseLink JPA Extensions for JDBC Connection Communication』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_JDBC

9.1.6 ツール

9.2項「TopLinkが有効なアプリケーションの監視および最適化」に説明されているように、TopLinkには監視ツールと最適化ツールが用意されています。

9.2 TopLinkが有効なアプリケーションの監視および最適化

パフォーマンス・チューニングにおける最も重要な課題は、最適化の対象を知ることです。アプリケーションのパフォーマンスを向上させるには、アプリケーションの中で稼働時の効率が最大に達していない領域を特定します。この項では、次のことを説明します。

- パフォーマンス最適化の推奨事項およびヒント

- タスク1: TopLinkプロファイラによるTopLinkパフォーマンスの測定

- タスク2: アプリケーションのパフォーマンス問題の原因特定

- タスク3: パフォーマンスが悪いアプリケーション・コンポーネントの変更

- タスク4: パフォーマンスの再測定

9.2.1 パフォーマンス最適化の推奨事項およびヒント

Oracle TopLinkには、アプリケーションのパフォーマンスを測定し、最適化するための様々な機能が用意されています。ほとんどの機能はディスクリプタまたはセッションで有効または無効にできるので、向上したパフォーマンスをグローバルに適用できます。開発サイクルのどの段階でもパフォーマンスを考慮する必要があります。これは、設計および実装作業の中でパフォーマンスの問題を認識していることを意味しますが、最初の試みで最高のパフォーマンスを達成する必要があるわけではありません。

たとえば、最適化によって設計が複雑になる場合は、最適化作業を最終的な開発フェーズに回します。それでも、後の統合が簡単になるように、最初の段階から最適化の計画を立てることは必要です。

TopLinkアプリケーションのチューニングに関連した最も重要な概念は、対話方式という考え方です。アプリケーションをチューニングする最も効果的な方法は、次のタスクを実行することです:

- タスク1: TopLinkプロファイラによるTopLinkパフォーマンスの測定

- タスク2: アプリケーションのパフォーマンス問題の原因特定

- タスク3: パフォーマンスが悪いアプリケーション・コンポーネントの変更

- タスク4: パフォーマンスの再測定

9.2.2 タスク1: TopLinkプロファイラによるTopLinkパフォーマンスの測定

TopLinkパフォーマンス・プロファイラは、指定のセッション内で実行されたすべての問合せのパフォーマンス統計をロギングすることにより、パフォーマンスの問題を識別するために役立ちます。

TopLinkパフォーマンス・プロファイラでは、次の情報がログ・ファイルに記録されます。

表9-1 TopLinkパフォーマンス・プロファイラでログに記録される情報

ログに記録される情報

説明

問合せクラス

問合せクラス名。

ドメイン・クラス

ドメイン・クラス名。

合計時間

ネストされた問合せを含む、問合せの合計実行時間(ミリ秒)。

ローカル時間

ネストされた問合せを除く、問合せの実行時間(ミリ秒)。

オブジェクト数

影響を受けたオブジェクトの合計数。

1秒当たりのオブジェクト処理数

トランザクション時に一秒当たりに処理されたオブジェクト数。

ロギング

ロギング・メッセージの出力に費やされた時間(ミリ秒)。

SQL準備

SQLスクリプトの準備に費やされた時間(ミリ秒)。

SQL実行

SQLスクリプトの実行に費やされた時間(ミリ秒)。

行フェッチ

データベースからの行のフェッチに費やされた時間(ミリ秒)

キャッシュ

オブジェクト・キャッシュの検索または更新に費やされた時間(ミリ秒)

オブジェクト・ビルド

ドメイン・オブジェクトの作成に費やされた時間(ミリ秒)

問合せ準備

実行する前に問合せの準備に費やされた時間(ミリ秒)

SQL生成

SQLスクリプトをデータベースに送信する前にSQLスクリプトの生成に費やされた時間(ミリ秒)

9.2.2.1 TopLinkプロファイラの有効化

TopLinkパフォーマンス・プロファイラは、org.eclipse.persistence.tools.profiler.PerformanceProfilerクラスのインスタンスです。有効にするには、次の行をpersistence.xmlファイルに追加します。

<property name="eclipselink.profiler" value="PerformanceProfiler.logProfiler"/>

TopLinkプロファイラの有効化に加えて、PerformanceProfilerクラスのパブリックAPIでも、表9-2で説明する機能が提供されています。

表9-2 PerformanceProfilerの追加機能

目的

使用するメソッド

プロファイラを無効にします。

dontLogProfile

操作統計などの各操作プロファイルのすべてのサマリーに、プロファイラがログインするように編成します。操作統計にはプロファイリングされたすべての操作の最短時間、すべての操作の合計時間、プロファイリングされた問合せによって返されたオブジェクトの数、プロファイリングされた各種操作に要した合計時間などがあります。

logProfileSummary

プロファイラ・ログを、各操作プロファイルを問合せ別にまとめたサマリーとして編成します。

logProfileSummaryByQuery

プロファイラ・ログを、各操作プロファイルをクラス別にまとめたサマリーとして編成します。

logProfileSummaryByClass

9.2.2.2 プロファイラの結果へのアクセスおよび解釈

プロファイリングの結果は、メモ帳などのテキスト・エディタでプロファイル・ログを開けば表示できます。

プロファイラ出力ファイルには、TopLinkが有効なアプリケーションのヘルスが示されています。

例9-4にTopLinkのプロファイラ出力サンプルを示します。

例9-4 パフォーマンス・プロファイラの出力

Begin Profile of{
ReadAllQuery(com.demos.employee.domain.Employee)
Profile(ReadAllQuery,# of obj=12, time=139923809,sql execute=21723809,
prepare=49523809, row fetch=39023809, time/obj=11623809,obj/sec=8)
} End Profile

例9-4に、問合せに関する次の情報を示します。

- ReadAllQuery(com.demos.employee.domain.Employee): プロファイリングした問合せとその引数

- Profile(ReadAllQuery): プロファイルの開始と問合せのタイプ

- # of obj=12: 問合せに関与したオブジェクトの数

- time=139923809: 問合せの合計実行時間(ミリ秒)

- sql execute=21723809: SQL文の実行に要した合計時間

- prepare=49523809: SQL文の準備に要した合計時間

- row fetch=39023809: データベースからの行のフェッチに要した合計時間

- time/obj=116123809: 各オブジェクトで要した時間(ナノ秒)

- obj/sec=8: 1秒当たりのオブジェクト処理数

9.2.3 タスク2: アプリケーションのパフォーマンス問題の原因特定

アプリケーションでパフォーマンスの問題が起こる可能性のある部分は、次のとおりです。

- 一般的なパフォーマンスの最適化の識別

- スキーマ

- マッピングおよびディスクリプタ

- セッション

- キャッシュ

- データ・アクセス

- 問合せ

- 作業ユニット

- アプリケーション・サーバーとデータベースの最適化

「タスク3: パフォーマンスが悪いアプリケーション・コンポーネントの変更」では、これらの各領域に対処するための簡単なガイドラインを説明します。

9.2.4 タスク3: パフォーマンスが悪いアプリケーション・コンポーネントの変更

9.2.3項「タスク2: アプリケーションのパフォーマンス問題の原因特定」に示されているアプリケーションのパフォーマンス問題の各原因に対して、この項で説明されている回避策を試みることができます。

9.2.4.1 一般的なパフォーマンスの最適化の識別

アプリケーションで必要な場合を除き、TopLinkのデフォルト動作をオーバーライドしないでください。デフォルトの中には、開発環境に適したものがあります。そのようなデフォルトについては、本番環境に合わせて変更してください(http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_for_a_Production_EnvironmentにあるEclipseLinkオンライン・ドキュメントの『Optimizing for a Production Environment』を参照)。

手動でコーディングするのではなく、ワークベンチを使用してください。これらのツールは使用しやすいだけでなく、デプロイXML(および必要に応じて生成されたコード)にエクスポートされるデフォルト構成は、ほとんどのアプリケーションに対して最適化されたベスト・プラクティスを示します。

9.2.4.2 スキーマ

データベース・スキーマおよびオブジェクト・モデルを設定する際には、最適化を考慮することが重要です。パフォーマンスの問題のほとんどは、オブジェクト・モデルやデータベース・スキーマが複雑すぎて、データベースが遅く、問合せが難しい場合に発生します。これが発生する可能性が高いのは、複雑なオブジェクト・モデルからデータベース・スキーマを直接導出した場合です。

パフォーマンスを最適化するには、オブジェクト・モデルとデータベース・スキーマを一緒に設計します。ただし、各モデルを最適に設計してください。これら2つが1対1に対応する必要はありません。

EclipseLinkオンライン・ドキュメントの『Optimizing Schema』(http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_Schema)には、目的とするパフォーマンスを実現するスキーマを設計するために役立つ4つのスキーマ最適化シナリオが説明されています。

9.2.4.3 マッピングおよびディスクリプタ

マッピングおよびディスクリプタにパフォーマンスのボトルネックが見つかった場合は、次の解決策を試みてください。

- 常にインダイレクション(遅延ロード)を使用します。インダイレクションは、最適化するデータベース・アクセスでクリティカルであるだけでなく、これによってキャッシュ・アクセスおよび作業ユニットの処理の最適化など、TopLinkでその他複数の最適化を実行できます。次のEclipseLinkオンライン・ドキュメントの『Configuring Indirection (Lazy Loading)』を参照してください。
http://wiki.eclipse.org/Configuring_a_Mapping_%28ELUG%29#Configuring_Indirection_.28Lazy_Loading.29

- TopLinkのマッピングでメソッド・アクセスを使用しないようにします。特に、getメソッドまたはsetメソッドに負荷の高い、または副次的な危険性のあるコードが存在する場合は、メソッド・アクセスのかわりにデフォルトの属性アクセスを直接使用してください。次のEclipseLinkオンライン・ドキュメントの『Configuring Method or Direct Field Accessing at the Mapping Level』を参照してください。
http://wiki.eclipse.org/Configuring_a_Descriptor_%28ELUG%29#Configuring_Cache_Existence_Checking_at_the_Descriptor_Level

- アプリケーションで必要な場合以外は、存在チェック・オプションcheckCacheThenDatabaseをディスクリプタで使用しないようにします。デフォルトの存在チェック動作の方がパフォーマンスに優れています。次のEclipseLinkオンライン・ドキュメントの『Configuring Cache Existence Checking at the Descriptor Level』を参照してください。
http://wiki.eclipse.org/Configuring_a_Mapping_%28ELUG%29#Configuring_Method_or_Direct_Field_Accessing_at_the_Mapping_Level

- TopLinkでオブジェクトのインスタンス化に使用するデフォルト・コンストラクタで、初期化に高い負荷をかけないようにします。そのかわりに、遅延初期化またはTopLinkのインスタンス化ポリシーを使用してディスクリプタを構成し、別のコンストラクタを使用します。次のEclipseLinkオンライン・ドキュメントの『Configuring Instantiation Policy』を参照してください。
http://wiki.eclipse.org/Configuring_a_Descriptor_%28ELUG%29#Configuring_Instantiation_Policy

9.2.4.4 セッション

セッションのパフォーマンスがアプリケーションの妨げになっている可能性がある場合は、次の解決策を試みてください。

- データベース・セッションではなく、サーバー環境のサーバー・セッションを使用します。

- リモート・セッションではなく、TopLinkのクライアント・セッションを使用します。クライアント・セッションは、ほとんどのマルチユーザーJava EEアプリケーション・サーバー環境に適しています。

- クライアント・セッションをプールしないでください。セッションをプールしても、パフォーマンスは向上しません。

- セッションの読取り/書込み接続プールのサイズを同時スレッド数に適した値(50など)に増やします。この構成は、内部接続プールの使用時はTopLinkで、外部接続プールの使用時はデータ・ソースで行えます。

その他の参考資料のリストは、次のEclipseLinkオンライン・ドキュメントの『Optimizing Sessions』を参照してください。

http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_Sessions

9.2.4.5 キャッシュ

多くの場合、キャッシュ・コーディネーションを実装すると、キャッシュ・パフォーマンスを向上できます。キャッシュ・コーディネーションでは、分散される可能性のある複数のセッションのインスタンスが相互にオブジェクト変更を送信できるようになるので、各セッションのキャッシュは最新の状態を保つことができます。キャッシュ動作の最適化の詳細は、次のEclipseLinkオンライン・ドキュメントの『Optimizing Cache』を参照してください。

http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_Cache

9.2.4.6 データ・アクセス

TopLinkでは、自分のアプリケーションからアクセスするデータ・ソースのタイプによって、低レベルのデータ読取りと書込みのパフォーマンス調整に使用できる、様々なLoginオプションを提供します。より高レベルのデータの読取りおよび書込みの最適化の詳細は、『Optimizing Data Access』(http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_Data_AccessのEclipseLinkオンライン・ドキュメント)に、アプリケーションのデータ・アクセス・パフォーマンスを向上させる方法がいくつか説明されています。そこでは、次の方法が説明されています。

- JDBCドライバ・プロパティの最適化

- データ形式の最適化

- バッチ書込みを使用した最適化

- 外部結合読取りと継承先サブクラスの使用

- パラメータ化されたSQL(パラメータ・バインド)とプリコンパイルされたSQL文のキャッシュを使用した最適化

9.2.4.7 問合せ

TopLinkでは、データの読取り、書込みおよび更新用の問合せAPIを幅広く提供しています。『Optimizing Queries』(http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_QueriesのEclipseLinkオンライン・ドキュメント)には、アプリケーションの問合せパフォーマンスを向上させる方法がいくつか説明されています。そこでは、次の方法が説明されています。

- パラメータ化されたSQLとプリコンパイルされたSQL文のキャッシュを使用した最適化

- 名前付き問合せを使用した最適化

- バッチ読取りと結合読取りを使用した最適化

- 部分オブジェクト問合せとフェッチ・グループを使用した最適化

- 読取り専用問合せを使用した最適化

- JDBCフェッチ・サイズを使用した最適化

- カーソル付きストリームとスクロール可能カーソルを使用した最適化

- 結果セットのページ区切りを使用した最適化

ここには、読取りおよび書込みの最適化の例へのリンクも示されています。

9.2.4.8 作業ユニット

作業ユニットを使用する際に最高のパフォーマンスを得るため、次のヒントを検討してください。

- オブジェクトを作業ユニットに登録するのは、オブジェクトが変更対象である場合にかぎります。変更されないオブジェクトを登録すると、作業ユニットは不必要にそのオブジェクトをクローン化して処理することになります。

- 新規または既存のオブジェクトを登録する際には、存在チェックの負荷を回避します。詳細は、次のEclipseLinkドキュメントの『How to Use Registration and Existence Checking』を参照してください。
http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#How_to_Use_Registration_and_Existence_Checking

- 変更されないとわかっているクラスについては、そのクラスが読取り専用であることを作業ユニットに指示し、チェンジ・セット計算の負荷を回避します。詳細は、次のEclipseLinkオンライン・ドキュメントの『Declaring Read-Only Classes』を参照してください。
http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#Declaring_Read-Only_Classes

- 作業ユニットでReadAllQueryによって読み取られるオブジェクトを変更する予定がない場合は、そのオブジェクトを登録解除し、チェンジ・セット計算の負荷を回避します。詳細は、次のEclipseLinkオンライン・ドキュメントの『How to Unregister Working Clones』を参照してください。
http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#How_to_Unregister_Working_Clones

- 一致する問合せを使用する前に、それが必要であることを確認します。代替方法は、次のEclipseLinkオンライン・ドキュメントの『Using Conforming Queries and Descriptors』を参照してください。
http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#Using_Conforming_Queries_and_Descriptors

- ウィービングと変更追跡を有効にすると、トランザクションのパフォーマンスを大幅に向上できます。詳細は、次のEclipseLinkオンライン・ドキュメントの『Optimizing Using Weaving』を参照してください。
http://wiki.eclipse.org/Optimizing_the_EclipseLink_Application_%28ELUG%29#Optimizing_Using_Weaving

パフォーマンスの測定で、作業ユニットのコミット中にパフォーマンスの問題があることを示している場合は、関連するオブジェクトのタイプとその一般的な変更方法に応じて、オブジェクト・レベルまたは属性レベル変更追跡の使用を検討してください。詳細は、次のEclipseLinkオンライン・ドキュメントの『Unit of Work and Change Policy』を参照してください。

http://wiki.eclipse.org/Introduction_to_EclipseLink_Transactions_%28ELUG%29#Unit_of_Work_and_Change_Policy

9.2.4.9 アプリケーション・サーバーとデータベースの最適化

アプリケーション・サーバーおよびデータベースのパフォーマンスを最適化するために、次の方法を検討してください。

- アプリケーション・サーバーおよびデータベースを正しく構成すると、パフォーマンスおよびスケーラビリティに大きく影響する場合があります。TopLinkアプリケーションおよび永続性の他に、アプリケーションのこれらの主要コンポーネントを正しく最適化していることを確認してください。

- アプリケーション・サーバーまたはJava EEサーバーの場合は、メモリー、スレッド・プール・サイズおよび接続プール・サイズが、サーバーで予測されるロードに十分であり、JVMの構成が最適であることを確認します。

- 最適なパフォーマンスと予測されるロードに対応できるように、データベースが正しく構成されていることを確認します。

9.2.5 タスク4: パフォーマンスの再測定

最後に、パフォーマンスのボトルネックになっている可能性のある場所を特定して、それらに対処した後、プロファイラを有効にしてアプリケーションを再実行します(9.2.2.1項「TopLinkプロファイラの有効化」を参照)。結果を検討し、さらに処置が必要な場合は、9.2.4項「タスク3: パフォーマンスが悪いアプリケーション・コンポーネントの変更」に示されている手順に従います。

10 HibernateからTopLinkへの移行

この章では、HibernateのJPA注釈およびネイティブな独自のAPIを使用するアプリケーションをTopLinkのJPAを使用するように移行する方法を説明します。この移行には、Hibernateの注釈をTopLinkのネイティブ注釈に移行すること、およびHibernateのネイティブAPIをTopLinkのJPAにアプリケーションのコードで変換することが関係しています。標準のJPA注釈およびAPIは変更されません。

この章には次の項が含まれます:

- 10.1項「Hibernateの理解」

- 10.2項「主なタスク」

- 10.3項「その他の参考資料」

10.1 Hibernateの理解

Hibernateは、Java環境のためのオブジェクト・リレーショナル・マッピング・ツールです。これは、Javaオブジェクトをリレーショナル・データベース・アーティファクトにマッピングしたり、Javaのデータ型をSQLのデータ型にマッピングしたりするためのフレームワークを提供します。また、データベースに問い合せて、データを取得することもできます。

Hibernateの詳細は、http://www.hibernate.orgを参照してください。

移行する理由

HibernateからTopLinkに移行する理由には、次のようなものがあります。

- パフォーマンスとスケーラビリティ: TopLinkのキャッシング・アーキテクチャでは、オブジェクトの作成を最小限に抑えて、インスタンスを共有できます。TopLinkのキャッシングでは、シングルノードおよびクラスタ化されたデプロイメントがサポートされています。

- 主要なリレーショナル・データベースのサポート: TopLinkでは、すべての主要なリレーショナル・データベースに固有の拡張機能が提供されて継続的にサポートされます。TopLinkはOracleデータベースに対する最高のORMソリューションでもあります。

- 包括的な永続性ソリューション: TopLinkには、業界をリードするオブジェクトリレーショナル・サポートが用意されていますが、さらにコア・マッピング機能も使用して、Object-XML (JAXB)、サービス・データ・オブジェクト(SDO)およびデータベースWebサービスが提供されています。要件に応じて、同じコア永続性エンジンに基づく永続性サービスを複数使用することもできます。

- JPAサポート: JPA 1.0仕様が同じく業界をリードしているので、OracleとTopLink/EclipseLinkのチームは、JDeveloper、ADF、SpringおよびEclipse IDE (Daliプロジェクト)との統合をサポートするJPA準拠のソリューションを提供することに注力しています。OracleはJPA 1.0のリファレンス実装を提供し、EclipseLinkはJPA 2.0のリファレンス実装を提供します。Oracleは、標準ベースの開発に注力しながら、多くの高度な機能を引き続き提供しています。

10.2 主なタスク

Hibernateを永続性プロバイダとして使用するアプリケーションをOracle TopLinkに移行するには、次のタスクを実行します。

- タスク1: Hibernateのエンティティ注釈の変換

- タスク2: Hibernateのカスタム・シーケンス・ジェネレータ注釈の変換

- タスク3: Hibernateのマッピング注釈の変換

- タスク4: persistence.xmlファイルの変更

- タスク5: Hibernate APIからEclipseLink APIへの変換

10.2.1 タスク1: Hibernateのエンティティ注釈の変換

org.hibernate.annotations.Entityクラスで定義されているHibernateのエンティティ注釈には、JPAの標準@Entity注釈で定義されている内容を超えるメタデータが追加されています。

例10-1に、Hibernateのエンティティ注釈のサンプルを示します。この例では、selectBeforeUpdate、dynamicInsert、dynamicUpdate、optimisticLockおよびpolymophism属性が使用されています。Hibernateのエンティティ注釈には、この例には示されていないmutableおよびpersister属性も定義されています。

例10-1 Hibernateのエンティティ注釈のサンプル

@org.hibernate.annotations.Entity(
selectBeforeUpdate = true,
dynamicInsert = true,
dynamicUpdate = true,
optimisticLock = OptimisticLockType.ALL,
polymorphism = PolymorphismType.EXPLICIT)

次の項では、選択、動的更新と挿入、ロックおよび多相性をTopLinkが処理する方法を説明します。詳細は、Eclipselinkドキュメントの『EclipseLink/Examples/JPA/Migration/Hibernate/V3Annotations』を参照してください。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Migration/Hibernate/V3Annotations

10.2.1.1 Select Before Update、Dynamic InsertおよびUpdate属性の変換

HibernateでselectBeforeUpdate属性を指定すると、オブジェクトが実際に変更されたことが確実な場合以外、HibernateはSQL UPDATEを実行しません。dynamicInsert属性を指定すると、INSERT SQLが実行時に生成されて、null以外の値の列のみが格納されます。dynamicUpdate属性を指定すると、UPDATE SQLが実行時に生成されて、値が変更された列のみを格納できます。

TopLinkのデフォルトでは、マップされたすべての列が常に挿入され、変更された列のみが更新されます。代替操作が必要な場合は、Javaコード、SQLまたはストアド・プロシージャを使用して、これらの操作に使用される問合せをカスタマイズできます。

10.2.1.2 Optimistic Lock属性の変換

Hibernateでは、optimisticLock属性によって、オプティミスティック・ロックの方式が決まります。

TopLinkのオプティミスティック・ロック機能では、Hibernateのすべてのロック・タイプに加えて他のタイプもサポートされています。表10-1に、Hibernateの@Entity(optimisticLock)属性からTopLinkのロッキング・ポリシーへの変換を示します。これらのポリシーは、TopLinkの@OptimisticLocking注釈またはTopLinkのorm.xmlファイルのどちらかで構成できます。詳細は、EclipseLinkドキュメントの『Using EclipseLink JPA Extensions for Optimistic Locking』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Optimistic_Locking

表10-1 HibernateのOptimisticLockからTopLinkのOptimisticLockingへの変換

HibernateのOptimisticLockタイプ

説明

EclipseLinkのOptimisticLocking

NONE

オプティミスティック・ロックなし

EclipseLinkはデフォルトでオプティミスティック・ロックなしになります。

VERSION

列バージョンを使用

JPA @Version注釈またはEclipseLinkの次の注釈を使用します。

@OptimisticLocking(type = OptimisticLockingType.VERSION_COLUMN)

DIRTY

変更された列を比較

JPA @Version注釈またはEclipseLinkの次の注釈を使用します。

@OptimisticLocking(type = OptimisticLockingType.CHANGED_COLUMNS)

ALL

すべての列を比較

EclipseLinkの次の注釈が使用されます

@OptimisticLocking(type = OptimisticLockingType.ALL_COLUMNS)

さらに、TopLinkでは、OptimisticLockingType.SELECTED_COLUMNS注釈を使用して、選択した列の特定のセットも比較できます。これにより、CHANGEDまたはALLの方式がニーズに合わない場合に、比較する必要がある重要な列を選択できます。

10.2.2 タスク2: Hibernateのカスタム・シーケンス・ジェネレータ注釈の変換

Hibernateでは、@GeneratedValue注釈によって、ID生成方式を定義します。@GenericGeneratorでは、Hibernate固有のIDジェネレータを定義できます。例10-2は、シーケンス値のカスタム・ジェネレータを示しています。

例10-2 シーケンス値のカスタム・ジェネレータ

...
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "mypackage.UUIDGenerator")
public String getTransactionGuid()
...

TopLinkでは、@GeneratedValue注釈を使用して、カスタム・シーケンス・ジェネレータを実装および登録できます。詳細は、EclipseLinkドキュメントの『How to use Custom Sequencing (i.e., UUID)』を参照してください。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/CustomSequencing

10.2.3 タスク3: Hibernateのマッピング注釈の変換

次の項では、Hibernateの様々な注釈をTopLinkの注釈に変換する方法を説明します。

10.2.3.1 @ForeignKey注釈の変換

Hibernateの@ForeignKey注釈では、スキーマ生成時に使用する外部キーの名前を定義できます。

TopLinkでは、妥当な名前が生成されますが、使用する名前を指定するための注釈やeclipselink-orm.xmlはサポートされていません。移行時には、TopLinkでスキーマ(DDL)コマンドをデータベースに直接生成するのではなく、スクリプト・ファイルに生成することをお薦めします。そうすれば、実行する前に、別の名前を使用するようにスクリプトをカスタマイズできます。

注意:

外部キー名はTopLinkでは実行時に使用されませんが、EclipseLinkがスキーマを削除しようとする場合には必要です。この場合、削除スクリプトをファイルに生成して、作成時に使用された外部キー名と一致するようにカスタマイズする必要があります。

10.2.3.2 @Cache注釈の変換

Hibernateでは、@Cache注釈によって、エンティティおよびリレーションシップのキャッシングを構成します。TopLinkでは、データ・キャッシュではなくエンティティ・キャッシュが使用されるので、リレーションシップは自動的にキャッシュされます。これらの場合、@Cache注釈を移行時に削除する必要があります。@Cache注釈がエンティティに使用されている場合は、TopLinkの@Cache注釈と同様の動作になります。@Cache注釈および同等のeclipselink-orm.xml構成値の詳細は、EclipseLinkドキュメントの『Eclipse User Guide on JPA Extensions』を参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Entity_Caching

10.2.4 タスク4: persistence.xmlファイルの変更

persistence.xmlファイルは、JPA永続性のデプロイメント・ディスクリプタ・ファイルです。ここには、永続性ユニットを指定し、管理対象永続性クラス、オブジェクト・リレーショナル・マッピング、およびデータベース接続の詳細を宣言します。例10-3に、Hibernateを使用するアプリケーションのpersistence.xmlファイルを示します。

例10-3 Hibernateを使用するアプリケーションの永続性ファイル

<persistence>
<persistence-unit name="helloworld">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>

10.2.4.1 変更されたpersistence.xml

例10-4に、TopLinkを使用するアプリケーション用に変更されたpersistence.xmlファイルを示します。主な相違は、永続性プロバイダの値などです。TopLinkの場合は、この値は、org.eclipse.persistence.jpa.PersistenceProviderです。TopLink固有のプロパティ名には、通常、eclipselink.target-databaseのようにeclipselinkという接頭辞が付きます。

例10-4 EclipseLink用に変更された永続性ファイル

<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="helloworld">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<!-- Entities must be specified for EclipseLink weaving -->
<class>Todo</class>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
<property name="eclipselink.weaving" value="false"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>

詳細は、EclipseLinkドキュメントの『EclipseLink/Examples/JPA/Migration/JBoss』を参照してください。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Migration/JBoss

10.2.4.2 データベースの削除および作成

本番環境では、通常はデータベースにスキーマが設定されています。永続性ユニットに定義されている次のプロパティは、例およびデモ用に適しています。これらのプロパティを指定すると、TopLinkでデータベース表が自動的に削除および作成されます。以前に存在した表は削除されます。

<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>

10.2.5 タスク5: Hibernate APIからEclipseLink APIへの変換

表10-2で、JPAプロジェクトでよく使用されるHibernateクラスおよび同等のEclipseLink (JPA)インタフェースを説明します。Hibernateのすべてのクラスはorg.hibernateパッケージにあります。すべてのJPAインタフェース(およびPersistenceクラス)はjavax.persistenceパッケージにあります。

EclipseLink APIの詳細は、『Oracle Fusion Middleware Java API Reference for EclipseLink』を参照してください。

表10-2 Hibernateのクラスおよび同等のJPAインタフェース

org.hibernate

javax.persistence

説明

cfg.Configuration

Persistence

セッション・ファクトリ(Hibernate内)またはエンティティ・マネージャ・ファクトリ(JPA内)を構成するブートストラップ・クラス。通常、これはJVM用の単一のセッション(またはエンティティ・マネージャ)ファクトリを作成するために使用します。

SessionFactory

EntityManagerFactory

Hibernateセッション(またはJPAエンティティ・マネージャ)をオープンして、ユーザー・リクエストを処理するためのAPIを提供します。一般に、セッション(またはエンティティ・マネージャ)は、クライアント・リクエストを処理するスレッドごとにオープンされます。

Session

EntityManager

エンティティをデータベースにストアまたはデータベースからロードするためのAPIを提供します。トランザクションを取得して問合せを作成するためのAPIも提供します。

Transaction

EntityTransaction

トランザクションを管理するためのAPIを提供します。

Query

Query

問合せを実行するためのAPIを提供します。

10.3 その他の参考資料

HibernateからEclipseLinkへの移行の詳細は、次のリンクのEclipseLink/Examples/JPA/Migration/Hibernateを参照してください。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Migration/Hibernate

A Oracle TopLinkのインストール

この付録では、Oracle TopLinkのインストールについて説明します。この章には次の項目があります。

- 付録A.1「システム要件および動作要件」

- 付録A.2「Oracle TopLinkのスタンドアロン・インスタンスのインストール」

- 付録A.3「Oracle WebLogic ServerでのOracle TopLinkおよびEclipseLinkのインストール」

- 付録A.4「Oracle Containers for Java EEでのOracle TopLinkのインストール」

- 付録A.5「Oracle Containers for Java EEでのEclipseLinkのインストール」

A.1 システム要件および動作要件

11gリリース1 (11.1.1.6.0)の完全な製品要件リストおよび最新の動作要件情報は、次を参照してください。

http://www.oracle.com/technology/products/ias/toplink/technical/support/index.html

A.1.1 その他の要件

TopLinkには、JDK 1.5.0 (またはそれ以降)と互換性のあるJava Virtual Machine (JVM)が必要です。また、TopLinkではURLベースのスキーマおよびホストにあるドキュメントを使用するためのインターネット・アクセスも必要です。

A.2 Oracle TopLinkのスタンドアロン・インスタンスのインストール

TopLinkスタンドアロン(TopLink Foundation LibraryおよびTopLink Workbenchを含む)をインストールするには、次の手順に従います。インストールを開始する前に、すべての既存のプロジェクト・データをバックアップしてください。

1. TopLink Zipファイル(toplink.zip)を空のディレクトリに解凍します。これが、Oracle TopLink 11gリリース1がインストールされる新しい<TOPLINK_HOME>ディレクトリになります。
解凍した後、Oracle TopLink Workbenchおよび他のユーティリティを実行するために追加の手順を実行する必要があります。詳細は、『Oracle Fusion Middleware Oracle TopLinkのための開発者ガイド』のTopLink Workbench環境の構成に関する項を参照してください。

2. インストールが完了したら、Oracle TopLinkリリース・ノートを参照してください。

A.3 Oracle WebLogic ServerでのOracle TopLinkおよびEclipseLinkのインストール

Oracle WebLogic Serverのインストールには、toplink.jarとeclipselink.jarの両方が含まれています。追加のインストールは不要です。構成情報の詳細は、『Oracle Fusion Middleware Oracle TopLink開発者ガイド』のOracle WebLogic ServerとTopLinkの統合に関する項を参照してください。

A.4 Oracle Containers for Java EEでのOracle TopLinkのインストール

TopLink (TopLink Foundation LibraryおよびTopLink Workbenchを含む)をOC4Jでインストールするには、次の手順に従います。インストールを開始する前に、すべての既存のプロジェクト・データをバックアップしてください。

1. OC4J Zipファイル(oc4j_extended.zip)を空のディレクトリに解凍します。これが、OC4J 10gがインストールされる新しい<ORACLE_HOME>ディレクトリになります。

2. TopLink Zipファイル(toplink.zip)を<ORACLE_HOME>ディレクトリに解凍します。<ORACLE_HOME>はOC4J 10gをインストールしたディレクトリです。
解凍した後、Oracle TopLink Workbenchおよび他のユーティリティを実行するために追加の手順を実行する必要があります。詳細は、『Oracle Fusion Middleware Oracle TopLinkのための開発者ガイド』のTopLink Workbench環境の構成に関する項を参照してください。

3. インストールが完了したら、Oracle TopLinkリリース・ノートを参照してください。

A.5 Oracle Containers for Java EEでのEclipseLinkのインストール

「Oracle Containers for Java EEでのOracle TopLinkのインストール」で説明されているように、EclipseLink (eclipselink.jar)はTopLinkのインストールに含まれています。

EclipseLinkをOC4Jに手動でインストールする方法の詳細は、http://wiki.eclipse.org/Integrating_EclipseLink_with_an_Application_Server_(ELUG)#Integrating_EclipseLink_with_Oracle_Containers_for_J2EE_.28OC4J.29にある『EclipseLink User's Guide』の「Integrating EclipseLink with Oracle Containers for Java EE」を参照してください。

Copyright © 2002, 2011, Oracle and/or its affiliates. All rights reserved.