この章では、複数のプロジェクト・タイプに共通のTopLinkプロジェクトのオプションを構成する方法について説明します。
この章の内容は次のとおりです。
表119-1は、構成可能なディスクリプタ・タイプと、そのタイプで対応している構成可能オプションが記載されたタイプ別の章への相互参照を示します。
表119-1 TopLinkディスクリプタの構成
| 作成対象 | 参照先 |
|---|---|
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
第26章「オブジェクト・リレーショナル・データ・タイプ・ディスクリプタの構成」 |
|
|
|
|
|
|
表119-2は、複数のTopLinkディスクリプタ・タイプによって共有される構成可能オプションを示します。
詳細は、次を参照してください。
表119-2は、複数のTopLinkディスクリプタ・タイプによって共有される構成可能オプションを示します。ここで説明する構成可能オプション以外にも、表119-1に示すように、特定のディスクリプタ・タイプについて説明しているオプションも構成する必要があります。
表119-2 共通ディスクリプタ・オプション
主キーとは、あるクラスの1つのインスタンスを同じタイプのその他すべてのインスタンスと区別する一意の識別子のことで、1つ以上の永続属性からなります。主キーは、リレーションシップの定義および問合せの定義に使用します。
表119-3に示すディスクリプタについては、主キーを構成する必要があります。また、そのクラスには主キーの構成に適した1つ以上の永続フィールドが必ず含まれるようにしてください。
表119-3では、どのディスクリプタが主キーをサポートしているかを示します。
表119-3 ディスクリプタでの主キーのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した主キーの構成方法 |
Javaを使用した主キーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
リレーショナル・クラス(非集約)ディスクリプタの場合は、そのディスクリプタの関連表から一意のデータベース・フィールドを1つ以上選択します(23.2項「関連表の構成」を参照)。
EISルート・ディスクリプタ(76.6項「EISディスクリプタのタイプ(ルートまたはコンポジット)の構成」を参照)の場合は、そのディスクリプタのスキーマ・コンテキストから一意の属性またはテキスト・ノードを1つ以上選択します(76.2項「EISディスクリプタのスキーマ・コンテキストの構成」を参照)。
ディスクリプタを1つ以上の主キーに関連付けるには、次の手順を実行します。
次の表を参照し、ディスクリプタの「ディスクリプタ情報」タブの「主キー」フィールドにデータを入力して、主キーを指定します。
| フィールド | 説明 |
|---|---|
| 主キー | 関連表の主キーを指定するには、「追加」をクリックして次の作業を行います。
主キーを削除するには、その主キーを選択して「削除」をクリックします。 |
Javaを使用すると、次のプロジェクトについて主キーを構成できます。
ClassDescriptorメソッドaddPrimaryKeyFieldNameを使用して、ディスクリプタの表の主キー・フィールドを指定します。このメソッドは、表の主キーを構成するフィールドごとにコールする必要があります。
ディスクリプタにこの他にも表が関連付けられており、これらの表にも同一の主キーがある場合は、ClassDescriptorメソッドaddPrimaryKeyFieldNameを使用して最初の表の主キーを指定します。
ディスクリプタにこの他にも表が関連付けられており、それらの表ごとに異なる主キーがある場合は、ClassDescriptorメソッドaddForeignKeyFieldNameForMultipleTableを使用してソースの外部キー・フィールド名をターゲットの主キー・フィールド名にマップします。
EISDescriptorメソッドaddPrimaryKeyFieldNameを使用して、ディスクリプタのクラスの主キー・フィールドを指定します。このメソッドは、主キーを構成するフィールドごとにコールしてください。
リレーショナル・クラス・ディスクリプタまたはEISルート・ディスクリプタは読取り専用として構成できます。これは、参照クラスのインスタンスが変更不可能になることを意味しています。
通常、読取り専用ディスクリプタは作業ユニット内でパフォーマンス向上のために使用します。これは、読取り専用クラスが登録、クローニングおよびマージする必要がないためです。詳細は、第113章「TopLinkトランザクションの概要」を参照してください。
CMPプロジェクトでは、TopLinkデプロイXMLファイル内でエンティティBeanを読取り専用として宣言できます。詳細は、119.3.1項「読取り専用EJB CMPエンティティBeanの使用方法」を参照してください。
表119-4では、どのディスクリプタが読取り専用構成をサポートしているかを示します。
表119-4 ディスクリプタでの読取り専用構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した読取り専用ディスクリプタの構成方法 |
Javaを使用した読取り専用ディスクリプタの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)
|
注意: リレーショナル集約ディスクリプタおよびEISコンポジット・ディスクリプタは、その所有者から読取り専用設定を取得します。 |
TopLinkでは、コンテナ管理の永続性を備えたエンティティBeanを読取り専用として宣言できます。これにより、エンティティBeanを変更不能にして、TopLinkが作業ユニットのパフォーマンスを最適化できるようになります。
読取り専用のエンティティBeanに対してなんらかの変更(作成、更新または削除)が試みられた場合、TopLinkはただちにjavax.ejb.EJBExceptionをスローします。つまり、トランザクションがコミットされるまでTopLinkが待機することはありません。
読取り専用のエンティティBeanのCMRフィールドの変更が試みられた場合、TopLinkはjavax.ejb.EJBExceptionをスローします。
TopLinkをOC4J永続マネージャとして構成すると、OC4J READ-ONLY CMP同時実行モードが、TopLinkの読取り専用Bean構成に置き換わります。
ディスクリプタを読取り専用として構成するには、次の手順を実行します。
そのディスクリプタを読取り専用にするかどうかを指定します。
ClassDescriptorメソッドsetReadOnlyを使用します。
一致機能とは、新規作成、変更または削除されたオブジェクトを、トランザクションのコミットを待たずに作業ユニットでの問合せに含めるための問合せ機能です。この機能を使用すると、データ・ソースの相対論理ビューまたは相対トランザクション・ビューに対する問合せを行うことができます。
表119-5では、どのディスクリプタがディスクリプタ・レベルでの作業ユニット一致機能をサポートしているかを示します。
表119-5 ディスクリプタでの作業ユニット一致機能のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでの作業ユニット一致機能の構成方法 |
Javaを使用したディスクリプタ・レベルでの作業ユニット一致機能の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)
作業ユニットでの結果を一致させるようにディスクリプタを構成した場合、その作業ユニットで問合せを実行すると、TopLinkにより、データ・ソースの結果セットが作業ユニットで行われた最新の変更内容に合せてフィルタ処理されます。新規オブジェクトまたは変更されたオブジェクトのうち、問合せの選択基準に適合しているオブジェクトは追加され、変更されたオブジェクトのうち、適合していないオブジェクトは削除されます。
|
注意: EISルート・ディスクリプタの場合、削除されたオブジェクトのみがフィルタ処理され、新規オブジェクトと変更されたオブジェクトはフィルタ処理されません。 |
一致機能を使用すると、パフォーマンスが低下することがあります。ディスクリプタで一致機能を有効にする前に、この機能の制限事項に注意し(115.4.1項「一致機能の使用方法」を参照)、一致機能が現実的に必要であるかどうかを確認してください。
例については、次を参照してください。
作業ユニットでのディスクリプタの結果を一致させるには、次の手順を実行します。
この一致機能の有効化または無効化: この機能を有効化すると、このディスクリプタのすべての問合せによるデータ・ソース結果は、作業ユニットでの最新の変更内容と一致するようになります。詳細は、115.4.1項「一致機能の使用方法」を参照してください。
ClassDescriptorメソッドsetShouldAlwaysConformResultsInUnitOfWork(true)を使用します。
EJB CMPでは、ディスクリプタ・エイリアスは、ejb-jar.xml属性abstract-schema-nameの値を指定するために使用します。これはEJB QL問合せで参照される論理名です。ディスクリプタ・エイリアスは、コンテナ管理の永続性を備えたエンティティBeanごとに構成する必要があります。デフォルトのディスクリプタ・エイリアスは、パス情報のないクラス名に設定されます。
表119-6では、どのディスクリプタがディスクリプタ・エイリアス構成をサポートしているかを示します。
表119-6 ディスクリプタでのディスクリプタ・エイリアス構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・エイリアスの構成方法 |
Javaを使用したディスクリプタ・エイリアスの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
![]() |
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
![]() |
|
EISディスクリプタ脚注1 |
|
|
![]() |
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
|
注意: このエイリアスはJPAでも使用されるエンティティ名です。これはJP QL問合せで参照される論理名です。デフォルトは、パス情報のないクラス名に設定されます。詳細は、『EclipseLink Developer's Guide』の「Introduction to EclipseLink JPA」( |
詳細は、次を参照してください。
ディスクリプタ・エイリアスを指定するには、次の手順を実行します。
ナビゲータで、ディスクリプタを選択します。
プロパティ・ウィンドウの「ディスクリプタ情報」タブをクリックします。
「ディスクリプタ・エイリアス」フィールドに、そのディスクリプタのエイリアスを入力します。詳細は、119.5項「ディスクリプタ・エイリアスの構成」を参照してください。
ClassDescriptorメソッドsetAliasにディスクリプタ・エイリアスをStringとして渡します。
ディスクリプタごとに自由形式のテキスト・コメントを定義できます。これらのコメントは任意の用途に使用できます。たとえば、ディスクリプタの目的または重要性など、プロジェクトの重要な実装詳細を記録することなどに使用できます。
コメントはTopLinkデプロイXMLファイルのTopLink Workbenchプロジェクトに格納されます。この機能に対応するJava APIはありません。
表119-7では、どのディスクリプタがディスクリプタ・コメント構成をサポートしているかを示します。
表119-7 ディスクリプタでのディスクリプタ・コメント構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・コメントの構成方法 |
Javaの使用方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
![]() |
|
![]() |
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
![]() |
|
EISディスクリプタ |
![]() |
|
![]() |
|
XMLディスクリプタ |
![]() |
|
![]() |
名前付き問合せとは、後から取得および実行できるように名前を付けて作成し、ディスクリプタのDescriptorQueryManager内に格納する、TopLinkの問合せの一種です。名前付き問合せは、一度作成すると、基礎となる関連オブジェクトすべてとともに後で効率的に再利用できるため、頻繁に実行される操作に適しており、アプリケーションのパフォーマンスを向上させることができます。
Classにおいてグローバルな名前付き問合せは、ディスクリプタ・レベルで構成します。または、名前付き問合せはセッション・レベルで構成することもできます(89.13項「セッション・レベルでの名前付き問合せの構成」を参照)。
名前付き問合せでSQL、EJB QLまたはTopLinkの式問合せを指定して、データ・ソースにアクセスします。
EJB CMPエンティティBeanディスクリプタの場合は、対応するエンティティBeanについて定義されたファインダごとに、名前付き問合せを1つ定義する必要があります。
|
注意: JPAで名前付き問合せを使用することもできます(『EclipseLink Developer's Guide』の「Using EclipseLink JPA Extensions for Stored Procedure Query」(http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Stored_Procedure_Query)を参照)。JPA名前付き問合せのスコープはセッションに対してグローバルであるため、各名前付き問合せには一意の名前があることを確認します。 |
Oracle JDeveloperまたはTopLink Workbenchを使用すると、問合せタイプのサブセットを名前付き問合せに構成し、ディスクリプタのDescriptorQueryManager内に格納できます(119.7.1項「TopLink Workbenchを使用したディスクリプタ・レベルでの名前付き問合せの構成方法」を参照)。
Javaを使用した場合は、あらゆる問合せタイプの名前付き問合せを作成し、ディスクリプタのDescriptorQueryManager内に格納できます(119.7.2項「Javaを使用したディスクリプタ・レベルでの名前付き問合せの構成方法」を参照)。
表119-8では、どのディスクリプタが名前付き問合せの構成をサポートしているかを示します。
表119-8 ディスクリプタでの名前付き問合せのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでの名前付き問合せの構成方法 |
Javaを使用したディスクリプタ・レベルでの名前付き問合せの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
CMPプロジェクトの場合は、問合せリストはejb-jar.xmlファイルに格納されます。問合せは、このファイル内で定義してからOracle JDeveloperまたはTopLink Workbenchに読み取ることも、「問合せ」タブで定義してからこのファイルに書き込むこともできます。詳細は、19.7項「ejb-jar.xmlファイルの使用」を参照してください。
作成した名前付き問合せは、後からTopLinkセッションで名前とクラスを指定して実行できます(109.3項「名前付き問合せの使用」を参照)。
名前付き問合せの詳細は、108.8項「名前付き問合せ」を参照してください。
名前付き問合せを作成するには、次の手順を実行します。
ナビゲータで、ディスクリプタを選択します。そのプロパティがエディタに表示されます。
エディタで「問合せ」タブをクリックします。「問合せ」タブが表示され、さらにその下に4つのタブが表示されます。
「問合せ」タブ内の「名前付き問合せ」タブをクリックします。「名前付き問合せ」タブが表示されます。
次の情報を参照し、このタブの各フィールドを指定します。
| フィールド | 説明 |
|---|---|
| 問合せ | 選択したディスクリプタの既存の問合せがリストされます。
|
| 問合せの種類 | 現在選択されている問合せの種類が表示されます(119.7.1.1項「名前付き問合せの追加」を参照)。 |
| クイック・ビュー | その問合せに定義されているパラメータと結合属性がリストされます。
「クイック・ビュー」領域内のヘッダーをクリックすると、それに対応するサブタブが選択されます。また、「クイック・ビュー」領域のパラメータ項目または属性項目を選択して「削除」をクリックすると、その項目を削除できます。 |
「名前付き問合せ」タブには、次のサブタブがあります。
一般: 119.7.1.2項「名前付き問合せのタイプとパラメータの構成」を参照してください。
選択基準: 119.7.1.3項「名前付き問合せの選択基準の構成」を参照してください。
順序: このタブはReadAllQuery問合せの場合にのみ表示されます。119.7.1.4項「すべて読取り問合せの順序の構成」を参照してください。
最適化: 119.7.1.5項「名前付き問合せの最適化の構成」を参照してください。
属性: このタブはReportQuery問合せの場合にのみ表示されます。119.7.1.6項「名前付き問合せの属性の構成」を参照してください。
グループ/順序: このタブはReportQuery問合せの場合にのみ表示されます。119.7.1.7項「名前付き問合せの「グループ/順序」オプションの構成」を参照してください。
コール: このタブはEISルート・ディスクリプタ(ReadAllQueryおよびReadObjectQuery問合せ)の場合にのみ表示されます。119.7.1.8項「名前付き問合せに関するEISインタラクションの作成」を参照してください。
オプション: 119.7.1.9項「名前付き問合せのオプションの構成」を参照してください。
次のダイアログ・ボックスを使用すると、新規の名前付き問合せを作成できます。
次の情報を参照し、このダイアログ・ボックス内で指定を行い、名前付き問合せを作成します。
| フィールド | 説明 |
|---|---|
| 多様性 | EJB CMPディスクリプタの場合にかぎり、次のいずれかの問合せの種類を選択する必要があります。 |
| TopLink名前付き問合せ | これを選択し、「タイプ」領域でタイプを指定すると、そのタイプの汎用TopLink問合せが作成されます。この名前付き問合せは、TopLinkセッションで、クラスと引数を渡して実行できます(109.3項「名前付き問合せの使用」を参照)。 |
| EJBファインダ | これを選択し、「タイプ」領域でタイプを指定すると、そのタイプのTopLink問合せが、入力した名前のEJB CMPファインダ・メソッドの実装として作成、使用されます。作成された問合せは、その名前のEJB CMPファインダ・メソッドをコールしたときにTopLinkランタイムによって実行されます。 |
| TopLink予約ファインダ | これを選択し、「タイプ」領域でタイプを指定すると、そのタイプのTopLink問合せが、指定した名前のTopLink予約ファインダ・メソッドの実装として作成、使用されます。作成された問合せは、その名前のEJB CMPファインダ・メソッドをコールしたときにTopLinkランタイムによって実行されます。
詳細は、108.15.1項「事前定義ファインダ」を参照してください。 |
| EJBセレクト | これを選択し、「タイプ」領域でタイプを指定すると、そのタイプのTopLink問合せが、EJB CMPライフ・サイクル・メソッドejbSelectの実装として作成、使用されます。作成された問合せは、ejbSelectメソッドをコールしたときにTopLinkランタイムによって実行されます。 |
| タイプ | 問合せのタイプを選択します。
注意: 「多様性」を「TopLink予約ファインダ」に設定した場合は、問合せの「タイプ」は選択できません。 |
| 名前 | この問合せの名前です。
|
脚注1 リレーショナル・ディスクリプタのみ。
必要な情報を入力し、「OK」をクリックします。TopLink Workbenchにより、その問合せが「名前付き問合せ」タブの問合せリストに追加されます。
次のタブを使用すると、問合せタイプを選択してパラメータを追加または削除できます。
次の情報を参照し、このタブの各フィールドを指定します。
| フィールド | 説明 |
|---|---|
| タイプ | リストから問合せのタイプを選択します。次のいずれかのタイプの問合せを作成できます。
他のタイプの問合せを作成するには、Javaを使用する必要があります(119.7.2項「Javaを使用したディスクリプタ・レベルでの名前付き問合せの構成方法」を参照)。 既存の問合せのタイプを変更する場合、古いタイプと新しいタイプ間に共通するすべての構成内容が保持されます。このため、タイプを変更すると新しいタイプにはない構成内容が失われることを警告するメッセージが表示されます。 |
| パラメータ | パラメータを取る問合せについては、そのパラメータを指定します。
|
| タイプ | パラメータのタイプのクラスを選択します。 |
| 名前 | パラメータ名を指定します。 |
脚注1 リレーショナル・ディスクリプタのみ。
次のタブを使用すると、名前付き問合せの書式を指定し、問合せ文字列を入力できます。
次の情報を参照し、このタブの各フィールドを指定します。
| フィールド | 説明 |
|---|---|
| タイプ | 問合せにTopLinkの「式」、「SQL」または「EJBQL」のいずれを使用するかを指定します。 |
| 式または問合せ文字列 | 「タイプ」フィールドに「SQL」または「EJBQL」を指定した場合は、問合せ文字列(SQLまたはEJB QL)を入力します。
TopLink Workbenchでは、問合せ文字列は検証されません。 問合せ構文の詳細は、この表の下の注意書きを参照してください。 |
|
注意: SQLまたはEJB QLを使用して問合せを定義する場合は、二重引用符のみ(")でなく、エスケープ文字と二重引用符(\")を使用してください。次に例を示します。SELECT OBJECT(employee) FROM Employee employee WHERE employee.name = \"Bob\" これに従わなかった場合、生成されるJavaコードは次のようになります。
query.setEJBQLString("SELECT OBJECT(employee) FROM Employee employee WHERE employee.name = "Bob"");
このコードでは、コンパイル時にエラーが発生します。 正しい構文で問合せを定義した場合は、エラーのない次のようなJavaコードが生成されます。
query.setEJBQLString("SELECT OBJECT(employee) FROM Employee employee WHERE employee.name = \"Bob\"");
|
このタブを使用して、すべて読取り問合せの結果を属性名順に順序付けします。
次のいずれかのアクションを選択します。
問合せ結果の順序付けの基準とする新しい属性を追加するには、「追加」をクリックします。「順序付け属性の追加」ダイアログ・ボックスが表示されます。順序付けの基準とするマップ済属性を選択し、昇順または降順を指定してから「OK」をクリックします。
既存の順序付け属性の順序を変更するには、その属性を選択して「上へ」または「下へ」をクリックします。
既存の順序付け属性の順序付けオプションを変更するには、その属性を選択して「編集」をクリックします。
既存の順序付け属性を削除するには、その属性を選択して「削除」をクリックします。
名前付き問合せは、バッチ属性(ReadAllQueryのみ)または結合属性(ReadAllQueryおよびReadObjectyQuery)を構成することにより最適化できます。
バッチ読取りの使用方法の詳細は、「問合せの最適化」、12.12.9.2項「読取り例2: オブジェクトのバッチ読取り」および109.2.1.9項「バッチ読取りの使用」を参照してください。
結合の詳細は、108.7.1.5項「結合読取りとオブジェクト・レベルの読取り問合せ」および109.2.1.10項「ObjectLevelReadQueryを使用した結合読取りの使用」を参照してください。
次のタブを使用すると、バッチ読取り属性と結合属性を指定できます。
「バッチ読取り属性」(ReadAllQueryのみ)では、次のいずれかのアクションを選択します。
新しいバッチ読取り属性を追加するには、「追加」をクリックします。「バッチ読取り属性の追加」ダイアログ・ボックスが表示されます。マップ済属性を選択し、「OK」をクリックします。
既存のバッチ読取り属性の順序を変更するには、その属性を選択して「上へ」または「下へ」をクリックします。
既存のバッチ読取り属性のオプションを変更するには、その属性を選択して「編集」をクリックします。
既存のバッチ読取り属性を削除するには、その属性を選択して「削除」をクリックします。
「結合属性」(ReadAllQueryおよびReadObjectQuery)では、次のいずれかのアクションを選択します。
新しい結合属性を追加するには、「追加」をクリックします。「結合属性の追加」ダイアログ・ボックスが表示されます。
マップ済属性を選択します。必要に応じて、「NULLを許容」チェック・ボックスを選択するかその選択を解除します。または、Collection属性の場合は、「Noneを許容」チェック・ボックスを選択するかその選択を解除します。「OK」をクリックします。
既存の結合属性の順序を変更するには、その属性を選択して「上へ」または「下へ」をクリックします。
既存の結合属性のオプションを変更するには、その属性を選択して「編集」をクリックします。
既存の結合属性を削除するには、その属性を選択して「削除」をクリックします。
ReportQuery問合せの場合にかぎり、1つ以上の属性に適用するレポート問合せ関数を構成できます。
レポート問合せの詳細は、108.7.5項「レポート問合せ」を参照してください。
次のタブを使用すると、レポート問合せ属性を構成できます。
「属性」(ReportQueryのみ)では、次のいずれかのアクションを選択します。
レポート問合せ属性を追加するには、「追加」をクリックします。「結合属性の追加」ダイアログ・ボックスが表示されます。119.7.1.6.1項「レポート問合せ属性の追加」に進みます。
既存のレポート問合せ属性の順序を変更するには、その属性を選択して「上へ」または「下へ」をクリックします。
既存のレポート問合せ属性のオプションを変更するには、その属性を選択して「編集」をクリックします。
既存のレポート問合せ属性を削除するには、その属性を選択して「削除」をクリックします。
|
注意: ダイレクト・マッピング(コンバータを含む)またはユーザー定義の問合せキーを使用して構成された属性を選択することのみが可能です。 |
次のダイアログ・ボックスを使用すると、レポート問合せ属性を追加できます。
このレポート問合せに必要な属性を選択し、次の表を参照してダイアログ・ボックス内で指定を行い、レポート問合せ属性を追加します。
| オプション | 説明 |
|---|---|
| 「Noneを許容」または「NULLを許容」 | 「NULLを許容」および「Noneを許容」オプションを使用すると、外部結合で使用する式を定義できます。
「NULLを許容」オプションを選択すると、
詳細は、110.2.7.2項「結合でのTopLink Expression APIの使用」を参照してください。 |
| ファンクション | TopLinkによって表示されるレポート問合せ関数のリストから選択します。この関数は、指定した属性に適用されます。Countを除くすべての関数について属性を指定する必要があります。
あるいは、データベースに実装するカスタム関数の名前を入力することもできます。詳細は、『Oracle Application Server TopLink API Reference』の |
| 名前 | 計算された値に付ける名前です。デフォルトの名前は<AttributeName><FunctionName>です。 |
必要な情報を入力し、「OK」をクリックします。TopLink Workbenchにより、レポート問合せ属性が「属性」タブの属性リストに追加されます。
ReportQuery属性の場合のみ、グループ化属性と順序付け属性を構成できます。
レポート問合せの詳細は、108.7.5項「レポート問合せ」を参照してください。
次のタブを使用すると、グループ化属性と順序付け属性を指定できます。
「グループ化属性」(ReportQueryのみ)では、次のいずれかのアクションを選択します。
新しいグループ化属性を追加するには、「追加」をクリックします。「グループ化属性の追加」ダイアログ・ボックスが表示されます。適切なマップ済属性を選択し、「OK」をクリックします。
既存のグループ化属性の順序を変更するには、その属性を選択して「上へ」または「下へ」をクリックします。
既存のグループ化属性のオプションを変更するには、その属性を選択して「編集」をクリックします。
既存のグループ化属性を削除するには、その属性を選択して「削除」をクリックします。
「順序付け属性」(ReportQueryのみ)では、次のいずれかのアクションを選択します。
新しい順序付け属性を追加するには、「追加」をクリックします。「順序付け属性の追加」ダイアログ・ボックスが表示されます。119.7.1.7.1項「順序付け属性の追加」に進みます。
既存の順序付け属性の順序を変更するには、その属性を選択して「上へ」または「下へ」をクリックします。
既存の順序付け属性のオプションを変更するには、その属性を選択して「編集」をクリックします。
既存の順序付け属性を削除するには、その属性を選択して「削除」をクリックします。
次のダイアログ・ボックスを使用すると、レポート問合せの順序付け属性を追加できます。
次の情報を参照し、このダイアログ・ボックスのフィールドを指定して、順序付け属性を追加します。
| オプション | 説明 |
|---|---|
| 選択した属性 | このオプションを選択すると、追加したレポート問合せ属性のリストが表示されます(119.7.1.6項「名前付き問合せの属性の構成」を参照)。
いずれかの属性を選択し、「順序」フィールドからその属性に対する順序付けオプションを選択してください。 |
| 新規属性 | このオプションを選択すると、すべてのクラス属性のリストが表示されます。
いずれかの属性を選択し、「順序」フィールドからその属性に対する順序付けオプションを選択してください。 |
| 順序 | 「昇順」または「降順」を選択します。 |
必要な情報を入力し、「OK」をクリックします。TopLink Workbenchにより、レポート問合せ属性が「属性」タブの属性リストに追加されます。
EISルート・ディスクリプタの場合は、EISインタラクションを定義してEISに対してメソッドを起動できます。
TopLinkを使用すると、読取り問合せおよびすべて読取り問合せのための名前付き問合せとして、次のようにインタラクションを定義できます。これらの問合せは、基本的な永続性操作の目的ではコールされません(76.5項「基本的な永続性操作用のカスタムEISインタラクションの構成」を参照)。これら追加の名前付き問合せは、特殊な目的のためにアプリケーション内からコールできます。
このタブを使用すると、読取り問合せおよびすべて読取り問合せのための名前付き問合せとしてインタラクションを定義できます。
次の情報を参照し、タブの各フィールドを指定します。
| フィールド | 説明 |
|---|---|
| インタラクションのタイプ | TopLink Workbenchを使用する場合は、「XMLインタラクション」のみを使用できます。このフィールドは変更できません。 |
| ファンクション名 | このコール・タイプ(「オブジェクトの読取り」または「すべて読取り」)がEISで起動するファンクションの名前を指定します。 |
| 入力レコード名 | 入力レコードの作成時にJCAアダプタに渡される名前を指定します。 |
| 入力ルート要素名 | 入力DOMに使用されるルート要素名を指定します。 |
| 入力引数 | 引数レコード内のインタラクション・フィールドまたはXPathノードにマップされる問合せ引数名を指定します。
たとえば、XMLレコードを使用している場合、このオプションを使用して入力引数 |
| 出力引数 | ディスクリプタのマッピングに使用されるレコード内の適切なノードをマップする、結果レコード・フィールドまたはXPathノードを指定します。
たとえば、XMLレコードを使用している場合、このオプションを使用して出力 対話でディスクリプタのマッピングと一致するXML結果が返される場合、出力引数は必要ありません。 |
| 入力結果のパス | EISインタラクションが、XMLレコードにネストされるインタラクション引数を予期する場合に、このオプションを使用します。
たとえば、引数を最初にルート要素 |
| 出力結果のパス | このオプションは、ネステッド構造内のオブジェクトにマップされたXMLデータがEISインタラクションの結果レコードに含まれる場合に使用します。
たとえば、最初に結果をルート要素 |
| プロパティ | EISプラットフォームに必要とされるプロパティを指定します。たとえば、プロパティ名operation(AQPlatform.QUEUE_OPERATIONから)およびプロパティ値enqueue(AQPlatform.ENQUEUEから)。 |
次のタブを使用すると、問合せの追加オプションを構成できます。
次の情報を参照し、タブの各フィールドを指定します。
| フィールド | 説明 |
|---|---|
| アイデンティティ・マップの問合せ結果のリフレッシュ脚注2 | 問合せ結果として得られたオブジェクト(1つ以上)の属性をリフレッシュします。カスケードを使用している場合には、オブジェクトのプライベート部分も含めてリフレッシュされます。 |
| ステートメントのキャッシュ脚注1 | プリコンパイルされたSQL文をキャッシュします。そのためには、すべてのパラメータのバインドも必要です(「パラメータのバインド」を参照)。 |
| パラメータのバインド脚注1 | デフォルトでは、TopLinkは問合せのパラメータをすべてバインドします。
このオプションの選択を解除し、バインドを無効にします。 |
| キャッシュの使用方法脚注2 | 問合せの実行時にTopLinkで行われるセッション・キャッシュの方法を、次の中から選択します。
詳細は、次を参照してください。 |
| インメモリ・インダイレクション脚注2 | インメモリー問合せまたは一致問合せの実行時にTopLinkで行われるインダイレクション(遅延ロード)処理の方法を、次の中から選択します。
詳細は、次を参照してください。 |
| 結果の選択脚注3 | TopLinkで行われるReportQuery結果の処理方法を、次の中から選択します。
詳細は、108.5.1項「コレクション問合せの結果」を参照してください。 |
| 主キーの取得脚注3 | 結果ごとにTopLinkに主キー値を取得させるかどうかを選択します。主キーを使用すると、実際のオブジェクトを取得できます。
|
脚注1 詳細は、12.11.5項「パラメータ使用のSQL(パラメータ・バインド)とプリコンパイルされたSQL文のキャッシュを使用した最適化方法」を参照してください。
脚注2 ReadObjectQueryおよびReadAllQuery問合せのみ。
脚注3 ReportQuery問合せのみ。
その他のオプションを構成するには、「詳細」をクリックします。119.7.1.10項「名前付き問合せの詳細オプションの構成」を参照してください。
関連項目
追加の詳細な問合せオプションを構成するには、次の手順を実行します。
「名前付き問合せ」タブ - 「オプション」タブ内の「詳細」ボタンをクリックします。「詳細な問合せオプション」ダイアログ・ボックスが表示されます。
「名前付き問合せ」タブ - 「オプション」タブ内の「詳細」ボタンをクリックします。「詳細な問合せオプション」ダイアログ・ボックスが表示されます。
「詳細な問合せオプション」ダイアログ・ボックスの各フィールドを指定します。
次の情報を参照し、各フィールドにデータを入力して「OK」をクリックします。
| フィールド | 説明 |
|---|---|
| キャッシュの維持 | 問合せにキャッシュを使用するか、データベースへの問合せ結果から直接オブジェクトを作成するかを指定します。このオプションは、部分オブジェクトの問合せを実行する場合にのみ使用してください(108.7.1.3項「部分オブジェクト問合せ」を参照)。部分オブジェクトの問合せでは結果がキャッシュされないためです。
詳細は、108.16.4項「読取り問合せ中のアイデンティティ・マップ・キャッシュの更新を無効にする方法」を参照してください。 |
| ラッパー・ポリシーの使用 | このディスクリプタに対して構成したラッパー・ポリシーを名前付き問合せに使用するかどうかを指定します。
詳細は、119.32項「ラッパー・ポリシーの構成」を参照してください。 |
| SQL文を一度だけ作成 | 名前付き問合せに対してsetShouldPrepare()を指定します。デフォルトでは、TopLinkによって問合せが最適化され、問合せのSQLが1回のみ生成されます。次のような引数を使用する動的SQLを必要とする特定のタイプの問合せについては、このオプションの選択を解除する必要があります。
|
| 問合せ結果のキャッシュ | 問合せに対してcacheQueryResultsメソッドを指定します。この問合せは、初回の実行時にのみデータベースにアクセスします。2回目からの実行では、初回とまったく同じ結果が返されます。
詳細は、111.13.1項「ReadQueryでの結果のキャッシュ方法」を参照してください。 |
| リモート・アイデンティティ・マップの問合せ結果のリフレッシュ | 問合せに対してrefreshRemoteIdentityMapResultメソッドを指定します。TopLinkにより、問合せ結果として得られたオブジェクト(1つ以上)の属性がリフレッシュされます。カスケードを使用している場合には、オブジェクトのプライベート部分も含めてリフレッシュされます。 |
| 排他接続 | この名前付き問合せで排他接続を使用するかどうかを指定します。また、セッション・レベルでの排他接続の取得を構成することもできます(89.12項「接続ポリシーの構成」を参照)。 |
| ペシミスティック・ロック | この問合せに対して特定のペシミスティック・ロック・ポリシーを指定するか、ディスクリプタにあるロック・ポリシーを使用します。 |
| DISTINCT句 | DISTINCT句が設定されている場合に、この句を出力するかどうかを指定します。DISTINCT句により、結果セットから重複を排除できます。 |
| 問合せタイムアウト | 指定の秒数が経過した時点で問合せをタイムアウト(中断)させるかどうかを指定します。 |
| 最大行 | 問合せの結果を指定の行数に制限するかどうかを指定します。このオプションは、非常に多くのオブジェクトを返す可能性のある問合せに対して設定します。 |
名前付き問合せをJavaで構成するには、ディスクリプタ修正メソッドを使用します(119.35項「修正メソッドの構成」を参照)。例119-1は、名前付き問合せを作成してDescriptorQueryManagerに追加する修正メソッドを示します。
例119-1 修正メソッドによる名前付き問合せの作成
public class EmployeeAmmendmentMethodClass {
....
// Create named query with Employee as its reference class
public static void createEmployeeQuery(ClassDescriptor descriptor) {
ReadObjectQuery query = new ReadObjectQuery(Employee.class);
ExpressionBuilder emp = query.getExpressionBuilder();
Expression firstNameExpression = emp.get("firstName").equal(emp.getParameter("firstName"));
query.setSelectionCriteria(firstNameExpression);
query.addArgument("firstName");
descriptor.getQueryManager().addQuery(
"employeeReadByFirstName", query);
}
}
あるディスクリプタの参照クラスに対する問合せの持続期間を、TopLinkランタイムがどのように処理するかを指定できます。ディスクリプタ・レベルで指定した問合せタイムアウトは、そのディスクリプタの参照クラスに対するすべての問合せに適用されます。問合せタイムアウトを指定すると、ある問合せがハングまたは長期化して適切な時間内に結果が返されない場合に、アプリケーションが永久的にブロックされるのを確実に回避できます。
表119-9では、どのディスクリプタが問合せタイムアウトの構成をサポートしているかを示します。
表119-9 ディスクリプタでの問合せタイムアウトの構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでの問合せタイムアウトの構成方法 |
Javaを使用したディスクリプタ・レベルでの問合せタイムアウトの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
タイムアウトは問合せ単位で構成することもできます。詳細は、次を参照してください。
選択したディスクリプタに対する問合せの持続期間をTopLinkランタイムがどのように処理するかを構成するには、次の手順を実行します。
ナビゲータでディスクリプタを選択します。そのプロパティがエディタに表示されます。
図119-20 ディスクリプタの「問合せ」 - 「設定」タブ、「問合せタイムアウト」のオプション

次の表を参照し、ディスクリプタの「設定」タブの各フィールドにデータを入力して、TopLinkによる問合せの持続期間の処理方法を指定します。
| フィールド | 説明 |
|---|---|
| デフォルト・タイムアウト | このディスクリプタに対する問合せが、親ディスクリプタに構成したタイムアウト期間内に終了しない場合に、TopLinkによってDatabaseExceptionがスローされます。親ディスクリプタが存在しないディスクリプタの問合せタイムアウトは、デフォルトでは「タイムアウトなし」に設定されます。 |
| タイムアウトなし | このディスクリプタに対する問合せが終了するまで、TopLinkはブロックされます。 |
| タイムアウト | タイムアウト期間を秒数で指定します。このタイムアウト期間内にこのディスクリプタに対する問合せが終了しない場合、TopLinkによってDatabaseExceptionがスローされます。 |
DescriptorQueryManagerメソッドsetQueryTimeoutに、タイムアウト値をミリ秒単位の数値で渡します。
TopLinkでは、デフォルトで、データ・ソースから読み取られたオブジェクトがキャッシュされます(第102章「キャッシュの概要」を参照してください)。それらのオブジェクトに対する後続の問合せではキャッシュがアクセスされるため、データ・ソースへのアクセスが削減され、様々なオブジェクトとそのリレーションシップの再作成コストが省けるので、パフォーマンスが向上します。すべて読取りなどの問合せでデータ・ソースがアクセスされた場合でも、返されるレコードに相当するオブジェクトがキャッシュ内にあれば、TopLinkではキャッシュのオブジェクトが使用されます。
ただし、この仕組みによってアプリケーション内のデータが最新のものでなくなる可能性があります。失効したデータや競合するデータがデータ・ソースにコミットされるのを防ぐには、適切なロック・ポリシーを使用することが唯一の解決策ですが(119.26項「ロック・ポリシーの構成」を参照)、アプリケーション内のデータに変更頻度の高いものがある場合には、競合が検出されたときのみでなく常にデータをリフレッシュすることをお薦めします。
ディスクリプタの参照クラスに対するすべての問合せのキャッシュ・リフレッシュを、TopLinkランタイムがどのように処理するかを指定できます。
表119-10では、どのディスクリプタが問合せのキャッシュ・リフレッシュの構成をサポートしているかを示します。
表119-10 ディスクリプタでの問合せのキャッシュ・リフレッシュのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したキャッシュ・リフレッシュ機能の構成方法 |
Javaを使用したキャッシュ・リフレッシュ機能の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
ディスクリプタ・レベルでのキャッシュ・リフレッシュを構成すると、パフォーマンスが低下することがあります。代替手段として、次を検討してください。
問合せ単位でのキャッシュ・リフレッシュ(108.16.5項「キャッシュのリフレッシュ方法」を参照)
キャッシュの有効期限(119.16項「ディスクリプタ・レベルでのキャッシュ有効期限の構成」を参照)
独立キャッシュ(102.2.7項「キャッシュの分離」を参照)
詳細は、12.10項「キャッシュの最適化」を参照してください。
選択したディスクリプタに対する問合せのキャッシュをTopLinkがどのようにリフレッシュするかを構成するには、次の手順を実行します。
ナビゲータでディスクリプタを選択します。そのプロパティがエディタに表示されます。
図119-21 ディスクリプタの「問合せ」 - 「設定」タブ、「キャッシュのリフレッシュ・オプション(高度な設定)」

次の表を参照し、ディスクリプタの「設定」タブの各フィールドにデータを入力して、TopLinkによる問合せのキャッシュ・リフレッシュ方法を指定します。
| フィールド | 説明 |
|---|---|
| 常にリフレッシュする | 問合せごとにキャッシュをリフレッシュします。
問合せでデータ・ソースにアクセスするたびにキャッシュ内の問合せ結果オブジェクトが確実にリフレッシュされるため、データが古くなるのを防ぐことができます。この設定は、データ・ソースにアクセスせずキャッシュ・ヒットを取得する問合せ(主キーによる読取り問合せやインメモリー問合せなど)には影響しません。 ディスクリプタ・レベルでのキャッシュ・リフレッシュを構成すると、パフォーマンスが低下することがあります。代替手段として、次を検討してください。
|
| 新規バージョンの場合のみリフレッシュする | データベース内のオブジェクトがキャッシュ内のオブジェクトよりも新しい(新しさの基準は、「オプティミスティック・ロック」フィールドでの設定に基づく)場合にのみ、キャッシュがリフレッシュされます。詳細は、119.26項「ロック・ポリシーの構成」を参照してください。
データ・ソースとバージョンが一致するオブジェクトが不必要にリフレッシュされなくなるため、パフォーマンスが向上します。このオプションは単独ではリフレッシュを実行しません。このオプションとともに、「常にリフレッシュする」、問合せのリフレッシュ(108.16.5項「キャッシュのリフレッシュ方法」を参照)、キャッシュの有効期限(119.16項「ディスクリプタ・レベルでのキャッシュ有効期限の構成」を参照)のいずれかを使用する必要があります。 |
| キャッシュ・ヒットを無効にする | このオプションを選択すると、TopLinkは、主キーに基づく読取り問合せの際にキャッシュを使用せず、データベースにアクセスします。このオプションを「常にリフレッシュする」と組み合せて使用すると、TopLinkが常にデータベースにアクセスするようになります。
このオプションでは、主キーに基づく読取り問合せを含むあらゆる問合せで、必ずデータ・ソースがアクセスされます。このオプションは単独ではリフレッシュを実行しません。このオプションとともに、「常にリフレッシュする」を使用する必要があります。 このオプションは、パフォーマンスを低下させるため、極力使用しないでください。 |
|
注意: 「常にリフレッシュする」および「キャッシュ・ヒットを無効にする」プロパティの使用に当たっては注意が必要です。パフォーマンスの低下を招く可能性があるためです。そのかわりに、問合せ単位でのキャッシュ・リフレッシュの構成(108.16.5項「キャッシュのリフレッシュ方法」を参照)、またはキャッシュの有効期限の構成(119.16項「ディスクリプタ・レベルでのキャッシュ有効期限の構成」を参照)を検討してください。キャッシュのパフォーマンスの詳細は、12.10項「キャッシュの最適化」を参照してください。 |
キャッシュ・リフレッシュ・オプションを構成するには、ClassDescriptorの次のメソッドを使用します。
setShouldAlwaysRefreshCache
setShouldAlwaysRefreshCacheOnRemote
setShouldDisableCacheHits
setShouldDisableCacheHitsOnRemote
setShouldOnlyRefreshCacheIfNewerVersion
これらのメソッドは、例119-2に示すように、ディスクリプタ修正メソッド(119.35項「修正メソッドの構成」を参照)内で使用します。
問合せキーとは、データベース・フィールド名の、スキーマ非依存の別名です。たとえば、データベース表EMPLOYEEのデータベース・フィールドF_NAMEに直接マップされた属性firstNameを持つクラスEmployeeについて考えてみます。問合せキーを使用しない場合は、Employee属性firstNameを含む問合せまたは式を作成するには、データベース管理システム固有のフィールド名F_NAMEを使用する必要があります。これでは問合せが作成しにくくなり、スキーマに依存して作成する必要があります。問合せキーを使用することで、スキーマに依存しない別名(firstNameなど)を使用してこのフィールドを参照できます。
表119-11では、どのディスクリプタが問合せキーをサポートしているかを示します。
表119-11 ディスクリプタでの問合せキーのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した問合せキーの構成方法 |
Javaを使用した問合せキーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
![]() |
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
問合せキーには次のような利点があります。
TopLink式でのコードの可読性が向上し、式の開発が容易になります。式を、オブジェクト・モデルのコンテキスト内で作成できます。
コードがデータベース・スキーマから独立するため、移植性が向上します。スキーマ内のフィールドの名前を変更する場合、問合せキーを使用しているコードを変更せずに問合せキーを再定義できます。
問合せキーをインタフェース・ディスクリプタと併用することで、インプリメンタ・ディスクリプタの表で異なるフィールド名を使用できます。
問合せキーは、すべてのマップ済属性で使用するために自動的に生成されます。問合せキーの名前は、オブジェクト・モデルで指定されたクラス属性の名前です。
問合せおよび式における問合せキーの使用方法の詳細は、108.2.7項「問合せキー」を参照してください。
問合せキーの生成のタイミング、および追加または変更方法は、使用するマッピングまたはディスクリプタのタイプによって異なります。
ダイレクト・マッピング
TopLink Workbenchでは、ダイレクト・マッピングを作成するときに、すべてのダイレクト・マッピングで使用される問合せキーが自動的に生成されます。
TopLink Workbenchには、オプティミスティック・ロックに使用されるversionフィールドや継承に使用されるtypeフィールドなど、ダイレクト・マッピングによってマップできる単純なアンマップ属性の問合せキーを追加および変更するための機能が用意されています。自動生成された問合せキーは変更および削除できません。
リレーションシップ・マッピング
TopLinkでは、すべてのリレーションシップ・マッピングで使用する問合せキーが実行時に自動的に生成されます。
たとえば、クラスCustomerの属性ordersが、1対多リレーションシップによってクラスPurchaseOrdersにマップされている場合、TopLinkランタイムではCustomerのこの属性用にordersという名前の問合せキーが生成されます。
Oracle JDeveloperおよびTopLink Workbenchでは現在、リレーションシップ・マッピング用の問合せキーの追加および変更はサポートされていません。この種の問合せキーを追加または変更するには、ディスクリプタ修正メソッドを使用して、そのためのJavaコードを作成する必要があります。
インタフェース・ディスクリプタ
インタフェース・ディスクリプタ(22.2.1.3項「リレーショナル・インタフェース・ディスクリプタの作成」を参照)には、それらのインプリメンタ間で共有される問合せキーのみを定義します。インタフェース・ディスクリプタには、問合せキーの名前のみを指定します。
TopLink Workbenchには、あるインタフェースのインプリメンタのうち、自動生成された共通の問合せキーを1つ以上共有するインプリメンタを選択するための機能が用意されています(119.11項「インタフェース問合せキーの構成」を参照)。
単純なアンマップ・フィールドに問合せキーを追加したり、ダイレクト・マッピング済の属性用に自動生成された問合せキーを表示するには、次の手順を実行します。
既存の問合せキーを削除するには、その問合せキーを選択して「削除」をクリックします。
既存の問合せキーの名前を変更するには、その問合せキーを選択して「名前の変更」をクリックします。
「フィールド」のドロップダウン・リストを使用すると、問合せキーに関連付ける表内のフィールドを選択できます。
リレーションシップ問合せキーを手動で作成するには、ClassDescriptorの次のいずれかのメソッドを使用して問合せキーを登録するディスクリプタ修正メソッドを実装します(119.35項「修正メソッドの構成」を参照)。
addQueryKey: QueryKeyのインスタンス(DirectQueryKey、DirectCollectionQueryKey、ManyToManyQueryKey、OneToManyQueryKey、OneToOneQueryKeyなど)を使用して問合せキーを指定します。
addDirectQueryKey: 指定したデータベース・フィールドにダイレクト・マップする問合せキーを追加します。
addAbstractQueryKey: 抽象問合せキーをインタフェース・ディスクリプタに追加します。そのインタフェースのすべてのインプリメンタには、抽象問合せキーで定義する問合せキーを定義する必要があります。
例119-3、例119-4および例119-5は、Javaコードで問合せキーを定義する方法を示します。
例119-3 問合せキーの定義
// Add a query key for the foreign key field using the direct method
descriptor.addDirectQueryKey("managerId", "MANAGER_ID");
// The same query key can also be added through the addQueryKey method
DirectQueryKey directQueryKey = new DirectQueryKey();
directQueryKey.setName("managerId");
directQueryKey.setFieldName("MANAGER_ID");
descriptor.addQueryKey(directQueryKey);
// Add a one-to-one query key for the large project of which the
// employee is a leader (this assumes only one project)
OneToOneQueryKey projectQueryKey = new OneToOneQueryKey();
projectQueryKey.setName("managedLargeProject");
projectQueryKey.setReferenceClass(LargeProject.class);
ExpressionBuilder builder = new ExpressionBuilder();
projectQueryKey.setJoinCriteria(builder.getField(
"PROJECT.LEADER_ID").equal(builder.getParameter("EMPLOYEE.EMP_ID")));
descriptor.addQueryKey(projectQueryKey);
例119-4 1対多問合せキーの定義
// Add a one-to-many query key for the projects where the employee // manages multiple projects OneToManyQueryKey projectsQueryKey = new OneToManyQueryKey(); projectsQueryKey.setName("managedProjects"); projectsQueryKey.setReferenceClass(Project.class); ExpressionBuilder builder = new ExpressionBuilder(); projectsQueryKey.setJoinCriteria(builder.getField( "PROJECT.LEADER_ID").equal(builder.getParameter("EMPLOYEE.EMP_ID"))); descriptor.addQueryKey(projectsQueryKey);
例119-5 多対多問合せキーの定義
// Add a many-to-many query key to an employee project that uses a join table
ManyToManyQueryKey projectsQueryKey = new ManyToManyQueryKey();
projectsQueryKey.setName("projects");
projectsQueryKey.setReferenceClass(Project.class);
ExpressionBuilder builder = new ExpressionBuilder();
projectsQueryKey.setJoinCriteria(
builder.getTable("EMP_PROJ").getField("EMP_ID").equal(
builder.getParameter("EMPLOYEE.EMP_ID").and(
builder.getTable("EMP_PROJ").getField("PROJ_ID").equal(
builder.getField("PROJECT.PROJ_ID")));
descriptor.addQueryKey(projectsQueryKey);
例119-6は、1対1問合せキーを定義するDescriptor修正メソッドの実装方法を示します。この例では、Addressクラスのオブジェクト・モデルには、このクラスを所有するEmployeeオブジェクトへの参照は含まれていません。この不足を補うには、Addressクラス・ディスクリプタを修正してownerという問合せキーを追加します。実行時に、このowner問合せキーに基づいてAddressオブジェクトを選択する式を作成できます。
例119-6 修正メソッドによる1対1問合せキーの定義
// Static amendment method in Address class, addresses do not know // their owners in the object model, however you can still // query on their owner if a user-defined query key is defined public static void addToDescriptor(Descriptor descriptor) { OneToOneQueryKey ownerQueryKey = new OneToOneQueryKey(); ownerQueryKey.setName("owner"); ownerQueryKey.setReferenceClass(Employee.class); ExpressionBuilder builder = new ExpressionBuilder(); ownerQueryKey.setJoinCriteria( builder.getField("EMPLOYEE.ADDRESS_ID").equal( builder.getParameter("ADDRESS.ADDRESS_ID"))); descriptor.addQueryKey(ownerQueryKey); }
問合せキーとは、データベース・フィールド名の、スキーマ非依存の別名です。問合せキーの詳細は、119.10項「問合せキーの構成」を参照してください。
インタフェース・ディスクリプタ(22.2.1.3項「リレーショナル・インタフェース・ディスクリプタの作成」を参照)は、それらのインプリメンタ間で共有される問合せキーでのみ定義します。インタフェース・ディスクリプタには、問合せキーの名前のみを指定します。
問合せキーは、インプリメンタ・ディスクリプタごとに、そのインプリメンタ・ディスクリプタのいずれかの表から選択した適切なフィールドを使用して定義する必要があります。
これにより、問合せキー名を使用して、インタフェース上に問合せとリレーションシップのマッピングを定義できます。
インタフェース問合せキーは、リレーショナル・データベース・プロジェクトでのみサポートされます。
表119-12では、どのディスクリプタがインタフェース問合せキーをサポートしているかを示します。
表119-12 ディスクリプタでのインタフェース問合せキーのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したインタフェース問合せキーの構成方法 |
Javaを使用したインタフェース問合せキーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
![]() |
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
タイプContactという連絡先を含むEmployeeについて考えてみます。Contactクラスは、PhoneおよびEmailという2つのインプリメンタを持つインタフェースです。Phoneクラスには属性idおよびnumberが定義されています。Emailクラスには属性idおよびaddressが定義されています。図119-23は、生成された問合せキーを示します。
どちらのクラスにも含まれる属性idは、それぞれ異なる名前のフィールドにダイレクト・マップされています。ただし、問合せキーはこの属性に対して生成されます。Contactインタフェース・ディスクリプタでは、id問合せキーをインプリメンタごとに定義することを指定する必要があります。
どちらのインプリメンタ・クラスにもid問合せキーを定義しなかった場合、そのディスクリプタには不備を示すフラグがOracle JDeveloperおよびTopLink Workbenchによって設定されます。
共有の問合せキーを持つディスクリプタをContactに対して定義し終わったら、これを可変1対1マッピング用の参照クラスとして使用できます(111.8項「可変1対1マッピングに対する問合せの使用」を参照)。
たとえば、Employeeのcontact属性に対して可変1対1マッピングを作成できます。このマッピングの外部キー・フィールドの情報を編集する場合は、Employeeディスクリプタの表をContactインタフェース・ディスクリプタからの問合せキーと一致させる必要があります。
あるインタフェースのインプリメンタのうち、自動生成された共通問合せキーを1つ以上共有するインプリメンタを選択するには、次の手順を実行します。
ナビゲータでインタフェース・ディスクリプタを選択します。そのプロパティがエディタに表示されます。
選択したインタフェースのインプリメンタのうち、共通の問合せキーを1つ以上共有するインプリメンタを選択するには、「追加」をクリックします。
選択したインタフェースのインプリメンタを削除するには、そのインプリメンタを選択して「削除」をクリックします。
例119-7は、ContactインタフェースとEmailおよびPhoneというインプリメンタをJavaで定義する方法を示します。
例119-7 インタフェース問合せキーの定義
Descriptor contactInterfaceDescriptor = new Descriptor();
contactInterfaceDescriptor.setJavaInterface(Contact.class);
contactInterfaceDescriptor.addAbstractQueryKey("id");
Descriptor emailClassDescriptor = new Descriptor();
emailClassDescriptor.setJavaClass(Email.class);
emailClassDescriptor.addDirectQueryKey("id", "E_ID");
emailClassDescriptor.getInterfacePolicy().addParentInterface(Contact.class);
emailClassDescriptor.setTableName("INT_EML");
emailClassDescriptor.setPrimaryKeyFieldName("E_ID");
emailClassDescriptor.setSequenceNumberName("SEQ");
emailClassDescriptor.setSequenceNumberFieldName("E_ID");
emailClassDescriptor.addDirectMapping("emailID", "E_ID");
emailClassDescriptor.addDirectMapping("address", "ADDR");
Descriptor phoneClassDescriptor = new Descriptor();
phoneClassDescriptor.setJavaClass(Phone.class);
phoneClassDescriptor.getInterfacePolicy().addParentInterface(Contact.class);
phoneClassDescriptor.addDirectQueryKey("id", "P_ID");
phoneClassDescriptor.setTableName("INT_PHN");
phoneClassDescriptor.setPrimaryKeyFieldName("P_ID");
phoneClassDescriptor.setSequenceNumberName("SEQ");
phoneClassDescriptor.setSequenceNumberFieldName("P_ID");
phoneClassDescriptor.addDirectMapping("phoneID", "P_ID");
phoneClassDescriptor.addDirectMapping("number", "P_NUM");
TopLinkキャッシュは、クラスと主キーの値に基づいて最近読み取られたり書き込まれたオブジェクトが格納される、インメモリー・リポジトリです。TopLinkでは、次の目的でこのキャッシュが利用されます。
最近読み取られたり書き込まれたオブジェクトを保持し、メモリー内でそれらにアクセスしてデータベースへのアクセスを最小限にすることで、パフォーマンスを向上させます。
ロックと分離レベルを管理します。
オブジェクト・アイデンティティを管理します。
表119-13では、どのディスクリプタがアイデンティティ・マップの構成をサポートしているかを示します。
表119-13 ディスクリプタでのアイデンティティ・マップのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでのキャッシュ・タイプとサイズの構成方法 |
Javaを使用したディスクリプタ・レベルでのキャッシュ・タイプとサイズの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
この構成は、アイデンティティ・マップのデフォルト構成(プロジェクト・レベルで定義)をオーバーライドします(117.10項「プロジェクト・レベルでのキャッシュ・タイプとサイズの構成」を参照)。
キャッシングとオブジェクト・アイデンティティの詳細、およびTopLinkのパフォーマンスを最大化するための推奨設定は、102.2.1項「キャッシュ・タイプおよびオブジェクト・アイデンティティ」を参照してください。
キャッシュの詳細は、第102章「キャッシュの概要」を参照してください。
ディスクリプタにアイデンティティ・マップ情報を指定するには、次の手順を実行します。
次の表を参照し、「キャッシング」タブの各フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| タイプ脚注1 | 「タイプ」のドロップダウン・リストから、次のいずれかのアイデンティティ・マップを選択します。
詳細は、102.2.1項「キャッシュ・タイプおよびオブジェクト・アイデンティティ」を参照してください。 プロジェクトのデフォルトのアイデンティティ・マップを変更しても、プロジェクト内の既存のディスクリプタには影響はありません。 |
| サイズ脚注1 | 次のようにキャッシュのサイズを指定します。
|
| デフォルト | キャッシュ・サイズを指定すると、この「デフォルト」チェック・ボックスの選択が解除されます。選択したキャッシュ・タイプのサイズをデフォルト値にリセットするには、「デフォルト」チェック・ボックスを選択します。 |
脚注1 ディスクリプタが継承階層内で子として定義されている場合、このフィールドはTopLinkによって読取り専用に設定され、親であるルート・ディスクリプタから継承したオプションが表示されます。詳細は、16.2.3.3項「継承」を参照してください。
目的のタイプのアイデンティティ・マップを使用できるようにディスクリプタを構成するには、ClassDescriptorの次のメソッドのいずれかを使用します。
useFullIdentitMap
useWeakIdentityMap
useSoftIdentityMap
useSoftCacheWeakIdentityMap
useHardCacheWeakIdentityMap
useNoIdentityMap
アイデンティティ・マップのサイズを構成するには、ClassDescriptorメソッドsetIdentityMapSizeを使用します。
独立セッションの使用を計画している場合(102.2.7項「キャッシュの分離」を参照)、独立セッションのキャッシュに限定するオブジェクトについて、ディスクリプタを分離するよう構成する必要があります。
ディスクリプタを分離するように構成するとは、TopLinkが共有セッション・キャッシュにオブジェクトを格納せず、オブジェクトがクライアント・セッション全体にわたって共有されないということを意味します。各クライアントは、独自のオブジェクトをデータベースから直接読み取ることになります。分離クライアント・セッション・キャッシュ内のオブジェクトは、親サーバー・セッションの共有セッション・キャッシュ内のオブジェクトを参照できますが、共有セッション・キャッシュ内のオブジェクトが分離クライアント・セッション・キャッシュ内のオブジェクトを参照することはできません。分離構成が必要となるのは、Oracle Database Virtual Private Database(VPD)のサポートまたはデータベース・ユーザー単位の読取りセキュリティを使用する場合です。また、全クライアント・セッションにわたるキャッシングが望ましくない場合にも分離構成を使用できます。
表119-14では、どのディスクリプタがキャッシュ分離構成をサポートしているかを示します。
表119-14 ディスクリプタでのキャッシュ分離構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでのキャッシュ分離の構成方法 |
Javaを使用したディスクリプタ・レベルでのキャッシュ分離の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
この構成は、デフォルトのキャッシュ分離構成(プロジェクト・レベルで定義)をオーバーライドします(117.11項「プロジェクト・レベルでのキャッシュ分離機能の構成」を参照)。
|
注意: 分離ディスクリプタとして構成したディスクリプタは、コーディネート・キャッシュに参加することはできません(119.15項「ディスクリプタ・レベルでのキャッシュ・コーディネーション変更伝播の構成」を参照)。 |
キャッシュ分離オプションを指定するには、次の手順に従います。
「分離」リストを使用して、次のいずれかを選択します。
独立: すべてのオブジェクトを分離クライアント・セッション・キャッシュ内でのみ使用可能にします。詳細は、102.2.7項「キャッシュの分離」を参照してください。
共有: すべてのオブジェクトを共有セッション・キャッシュ内で参照可能にします(デフォルト)。
特定のクラスを分離するには、ディスクリプタ修正メソッドを使用し(119.35項「修正メソッドの構成」を参照)、ClassDescriptorメソッドsetIsIsolatedをブール値true付きでコールします。
このポリシーを使用して、作業ユニットで特定クラスのセッション・キャッシュを使用する方法を決定します。表119-15は、作業ユニット・キャッシュ分離機能のオプションを示します。
表119-15 作業ユニット・キャッシュ分離機能のオプション
| オプション | 説明 |
|---|---|
|
トランザクション後にセッション・キャッシュを使用 |
このオプションでは、初期トランザクション後にキャッシュを使用できるため、最も効率的です。 |
|
トランザクション後に新規データを分離 |
これにより、事前にキャッシュされたオブジェクトは、初期トランザクション後に作業ユニット内でアクセスできますが、新規データから作成されたオブジェクトはすべて作業ユニット内にのみ格納されるため、コミット前のデータはセッション・キャッシュには配置されません。 |
|
トランザクション後にキャッシュを分離 |
注意: このオプションでは、初期トランザクション後にセッション・キャッシュを使用しないため、パフォーマンスに影響を与える可能性があります。 |
|
常にキャッシュを分離 |
注意: このオプションでは、セッション・キャッシュを使用しないため、パフォーマンスに影響を与える可能性があります。ただし、クラスを分離するか、クラスでペシミスティック・ロックを使用してトランザクション内で常にアクセスする場合、このオプションによりオブジェクトのコピーを2つ作成することを回避できます。 |
これらのオプションの多くは、次のような初期トランザクションの作業ユニットにのみ適用されます。
フラッシュされた作業ユニット(write changes)
変更問合せを発行した作業ユニット
ペシミスティック・ロックを取得した作業ユニット
特定のクラスを分離するには、ディスクリプタ修正メソッドを使用し(119.35項「修正メソッドの構成」を参照)、ClassDescriptorメソッドsetUnitOfWorkCacheIsolationLevelをコールします。
コーディネート・キャッシュの使用を計画する場合(102.3項「キャッシュ・コーディネーション」を参照)、コーディネート・キャッシュから特定のディスクリプタの変更を伝播する方法とその条件を構成できます。
表119-16では、どのディスクリプタがキャッシュ・コーディネーション変更伝播の構成をサポートしているかを示します。
表119-16 ディスクリプタでのキャッシュ・コーディネーション変更伝播の構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでのキャッシュ・コーディネーション変更伝播の構成方法 |
Javaを使用したディスクリプタ・レベルでのキャッシュ・コーディネーション変更伝播の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
この構成は、デフォルトのキャッシュ・コーディネーション変更伝播の構成(プロジェクト・レベルで定義)をオーバーライドします(117.12項「プロジェクト・レベルでのキャッシュ・コーディネーション変更伝播の構成」を参照)。
コーディネート・キャッシュの構成を完了するには、第103章「コーディネート・キャッシュの構成」を参照してください。
キャッシュ・コーディネーション変更伝播のオプションを指定するには、次の手順に従います。
次の情報を参照し、「コーディネーション」フィールドにデータを入力します。
| 「コーディネーション」オプション | 説明 | 使用する場合 |
|---|---|---|
| なし | 既存インスタンスおよび新規インスタンスの両方の場合に、変更通知を伝播しません。 | まれに読み取られる、または変更されるオブジェクトの場合。 |
| 変更の同期化 | 既存のインスタンスの場合、変更された各属性を含む変更通知を伝播します。
新規のインスタンスの場合、インスタンスがこの変更伝播オプションで構成された既存の他のオブジェクトに関連する場合のみ、オブジェクト作成がすべての新規インスタンスの属性とあわせて伝播されます。 |
頻繁に読み取られるまたは変更される、ほとんど属性のないオブジェクトの場合、または少数の属性のみが頻繁に変更される場合。
多数のリレーションシップまたは複雑なリレーションシップを持つオブジェクト |
| 変更および新規オブジェクトの同期化 | 既存のインスタンスの場合、変更された各属性を含む変更通知を伝播します。
新規インスタンスの場合、オブジェクト作成を、新規インスタンスのすべての属性とともに伝播します。 |
頻繁に読み取られるまたは変更される、ほとんど属性のないオブジェクトの場合、または少数の属性のみが頻繁に変更される場合。
ほとんどリレーションシップのない、または単純なリレーションシップを持つオブジェクトの場合。 |
| 変更済オブジェクトの無効化 | 既存のインスタンスの場合、他のすべてのセッションでオブジェクトを無効としてマークする、オブジェクトの無効化を伝播します。これにより、他のセッションは次回このオブジェクトを読み取るときに、セッションのキャッシュをデータ・ソースにより更新する必要があることがわかります。
新規インスタンスの場合、変更通知は伝播されません。 |
頻繁に読み取られるまたは変更される、多数の属性を含むオブジェクト、または多数の属性のみが頻繁に変更される場合。 |
ディスクリプタ修正メソッドを使用し(119.35項「修正メソッドの構成」を参照)、ClassDescriptorメソッドsetCacheSynchronizationTypeを次のいずれかのパラメータ付きで起動します。
ClassDescriptor.DO_NOT_SEND_CHANGES
ClassDescriptor.SEND_OBJECT_CHANGES
ClassDescriptor.SEND_NEW_OBJECTS_WITH_CHANGES
ClassDescriptor.INVALIDATE_CHANGED_OBJECTS
デフォルトでは、オブジェクトは明示的に削除されるまで(114.7項「オブジェクトの削除」を参照)、または弱アイデンティティ・マップの使用時はガベージ・コレクションされるまで、キャッシュに保持されます(117.11項「プロジェクト・レベルでのキャッシュ分離機能の構成」を参照)。あるいは、CacheInvalidationPolicyで自動または手動でオブジェクトが無効であると指定し、オブジェクトを構成できます。これにより、問合せで無効オブジェクトを読み取ろうとすると、TopLinkではそのオブジェクトの最新バージョンのデータ・ソースへアクセスし、その情報でキャッシュを更新します。
キャッシュ無効化の使用により、失効したデータがアプリケーションで使用されないようにします。これは常にリフレッシュ実行のよりよい代替方法です(119.9項「キャッシュ・リフレッシュ機能の構成」を参照)。
表119-17では、どのディスクリプタがキャッシュ無効化ポリシーをサポートしているかを示します。
表119-17 ディスクリプタでのキャッシュ無効化ポリシーのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでのキャッシュ有効期限の構成方法 |
Javaを使用したディスクリプタ・レベルでのキャッシュ有効期限の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
プロジェクト・レベルのキャッシュ無効化の構成(117.13項「プロジェクト・レベルでのキャッシュの有効期限の構成」を参照)は、ディスクリプタ・レベルまたは問合せレベル(111.13.2項「問合せレベルにおけるキャッシュの有効期限の構成方法」を参照)でキャッシュ無効化を定義してオーバーライドできます。
コーディネート・キャッシュを使用している場合は、効率性を高めるためオブジェクトが無効であると宣言されているという事実をTopLinkに通信する方法をカスタマイズできます。詳細は、119.15項「ディスクリプタ・レベルでのキャッシュ・コーディネーション変更伝播の構成」を参照してください。
詳細は、102.2.5項「キャッシュの無効化」を参照してください。
ディスクリプタにキャッシュ無効化情報を指定するには、次の手順に従います。
ナビゲータでディスクリプタを選択します。
エディタで「キャッシング」タブを選択します。「キャッシング」タブが表示されます。
次の表を参照し、「キャッシング」タブの各フィールドにデータを入力して、ディスクリプタにキャッシュ無効化ポリシーを指定します。
| フィールド | 説明 |
|---|---|
| プロジェクトのデフォルト | このディスクリプタにプロジェクトのキャッシュ有効期限オプションを適用します。詳細は、117.13項「プロジェクト・レベルでのキャッシュの有効期限の構成」を参照してください。 |
| 失効なし | キャッシュ内のオブジェクトは失効しないと指定します。 |
| 時間による失効 | キャッシュ内のオブジェクトは一定時間の経過後に失効すると指定します。「失効までの時間」フィールドを使用して、オブジェクトが失効するまでの時間(ミリ秒)を示します。 |
| 日次の失効 | キャッシュ内のオブジェクトは毎日特定の時間に失効すると指定します。「失効の時間」フィールドを使用して、オブジェクトが失効する正確な時刻を秒単位まで(24時間表記で)示します。 |
| 更新時に読取り時間を更新 | TopLinkがキャッシュされているオブジェクトを正常に更新した後、そのオブジェクトの有効期限をリセットするかどうかを指定します。 |
|
注意: これらのオプションは、ディスクリプタごとに適用されます。プロジェクト・レベルのオプションの構成の詳細は、117.13項「プロジェクト・レベルでのキャッシュの有効期限の構成」を参照してください。 |
CacheInvalidationPolicyの必要なインスタンスを設定するには、ClassDescriptorメソッドsetCacheInvalidationPolicyを使用します。
TopLinkでは、データベースにオブジェクトを書き込む際に、存在チェックを実行して挿入と更新のどちらを行うかを判断します。
デフォルトでは、TopLinkはキャッシュに対してチェックします。このデフォルトの存在チェック・オプションをほとんどのアプリケーションに対して使用することをお薦めします。データベースの存在チェックは、アプリケーションでのパフォーマンスのボトルネックの原因になる場合があります。
表119-18では、どのディスクリプタが存在チェックをサポートしているかを示します。
表119-18 ディスクリプタでの存在チェックのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したディスクリプタ・レベルでのキャッシュ存在チェックの構成方法 |
Javaを使用したディスクリプタ・レベルでのキャッシュ存在チェックの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
存在チェックをディスクリプタ・レベルで構成して、プロジェクト・レベルの構成をオーバーライドできます(117.7項「プロジェクト・レベルでの存在チェックの構成」を参照)。
詳細は、次を参照してください。
ディスクリプタに存在チェック情報を指定するには、次の手順に従います。
次の表を参照して、新規に作成するディスクリプタに存在チェックのオプションを指定するため、次のフィールドのデータを指定します。
| フィールド | 説明 |
|---|---|
| キャッシュのチェック | セッション・キャッシュをキャッシュします。オブジェクトがキャッシュ内に存在しない場合、オブジェクトは存在しないとみなします(挿入を行います)。オブジェクトがキャッシュ内に存在する場合、オブジェクトは存在するとみなします(更新を行います)。ほとんどのアプリケーションに対してこのオプションを使用することをお薦めします。 |
| キャッシュ、続いてデータベースのチェック | オブジェクトがキャッシュ内に存在しない場合、データベースに問い合せてオブジェクトが存在するかどうか判断します。オブジェクトが存在する場合、更新を行います。それ以外の場合、挿入を行います。このオプションを選択すると、パフォーマンスが低下する場合があります。詳細は、115.1.3.1項「「データベースのチェック」の使用」を参照してください。 |
| 存在すると仮定 | 常にオブジェクトが存在すると仮定します。常に更新を行います(挿入は行いません)。詳細は、115.1.3.2項「「存在すると仮定」の使用」を参照してください。 |
| 存在しないと仮定 | 常にオブジェクトが存在しないと仮定します。常に挿入を行います(更新は行いません)。詳細は、115.1.3.3項「「存在しないと仮定」の使用」を参照してください。 |
Javaを使用してディスクリプタ・レベルで存在チェックを構成するには、ClassDescriptorメソッドgetQueryManagerを使用してディスクリプタからDescriptorQueryManagerを取得した後、次のいずれかのDescriptorQueryManagerメソッドを使用します(例119-8を参照)。
checkCacheForDoesExist: セッション・キャッシュをチェックします。オブジェクトがキャッシュ内に存在しない場合、オブジェクトは存在しないとみなします(挿入を行います)。オブジェクトがキャッシュ内に存在する場合、オブジェクトは存在するとみなします(更新を行います)。ほとんどのアプリケーションに対してこのオプションを使用することをお薦めします。
checkDatabaseForDoesExist: オブジェクトがキャッシュに存在しない場合、データベースに問い合せてオブジェクトが存在するかどうか判断します。オブジェクトが存在する場合、更新を行います。それ以外の場合、挿入を行います。このオプションを選択すると、パフォーマンスが低下する場合があります。詳細は、115.1.3.1項「「データベースのチェック」の使用」を参照してください。
assumeExistenceForDoesExist: オブジェクトは存在するものと常に仮定して、更新を行います(挿入は行いません)。詳細は、115.1.3.2項「「存在すると仮定」の使用」を参照してください。
assumeNonExistenceForDoesExist: オブジェクトは存在しないものと常に仮定して、挿入を行います(更新は行いません)。詳細は、115.1.3.3項「「存在しないと仮定」の使用」を参照してください。
プロジェクトでEJB CMPまたはBMPを使用している場合は(117.5項「永続性タイプの構成」を参照)、ディスクリプタを使用してコンテナ管理の永続性またはBean管理の永続性を備えたエンティティBeanの特性を定義できます。
表119-19では、どのディスクリプタがEJB情報をサポートしているかを示します。
表119-19 ディスクリプタでのEJB情報のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したEJB CMPおよびBMP情報によるディスクリプタの構成方法 |
Javaを使用したEJB CMPおよびBMP情報によるディスクリプタの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ脚注2 |
|
|
|
|
XMLディスクリプタ |
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
そのためには、Enterprise Beanのマッピング時に、Beanクラスのディスクリプタを作成します。ただし、ローカル・インタフェース、リモート・インタフェース、ホーム・クラスまたは主キー・クラスのディスクリプタは作成しません。
TopLink Workbenchを使用する場合は、適切なエンティティBeanタイプ(コンテナ管理の永続性またはBean管理の永続性など)を使用してプロジェクトを定義し、Beanのejb-jar.xmlファイルをTopLink Workbenchプロジェクトにインポートする必要があります。
CMPプロジェクトについては、ejb-jar.xmlファイルでBeanのマップ対象属性を定義します。コンテナ管理の永続性を備えたエンティティBeanのディスクリプタには、CMP固有のオプションを構成するためのCMPポリシーを記述します。
詳細は、16.2.3項「ディスクリプタとCMPおよびBMP」を参照してください。
EJB情報を使用してディスクリプタを構成するには、次の手順に従います。
ナビゲータで、リレーショナル・ディスクリプタを選択します。

マッピング・ツールバーの「EJBディスクリプタ」ボタンをクリックします。
ディスクリプタのプロパティ画面に「EJB情報」タブが追加されます。
選択したディスクリプタからEJB情報を削除するには、「EJBディスクリプタ」ボタンをもう一度クリックします。
ディスクリプタのプロパティ画面から「EJB情報」タブが削除されます。
次の情報を参照し、タブの各フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| EJB名 | Beanのベース名を入力します。この情報はejb-jar.xmlファイルの<ejb-name>要素に指定されているため、このフィールドは表示専用になります。 |
| 主キー・クラス | 主キーを入力します。この情報はejb-jar.xmlファイルの<prim-key-class>要素に指定されているため、このフィールドは表示専用になります。 |
| 不明な主キー・クラス | コンテナ管理の永続性を持つエンティティBeanに対して、主キー・クラスまたは主キー・フィールドを指定しない場合は、このオプションを選択します。
たとえば、エンティティBeanに自然な主キーがない場合、またはデプロイ担当者にデプロイ時に主キー・フィールドを選択させる場合は、このオプションを選択します。詳細は、8.9.2項「EJB CMPの不明な主キー・クラスのサポートの構成方法」を参照してください。 |
| ローカル・インタフェース | ローカル・インタフェースを入力します。この情報はejb-jar.xmlファイルの<local>要素に指定されているため、このフィールドは表示専用になります。 |
| ローカル・ホーム・インタフェース | ローカル・ホーム・インタフェースを入力します。この情報はejb-jar.xmlファイルの<local-home>要素に指定されているため、このフィールドは表示専用になります。 |
| リモート・インタフェース | リモート・ホーム・インタフェースを入力します。この情報はejb-jar.xmlファイルの<remote>要素に指定されているため、このフィールドは表示専用になります。 |
| リモート・ホーム・インタフェース | リモート・ホーム・インタフェースを入力します。この情報はejb-jar.xmlファイルの<remote-home>要素に指定されているため、このフィールドは表示専用です。 |
| 遅延の変更 | この領域のオプションを使用して、このEJBディスクリプタに、TopLinkによるデータベースの更新方法を指定します。 |
| すべての変更を遅延 | JTAトランザクションがコミットされるまで、データベースに変更内容を送信しません。これはTopLinkのデフォルト動作です。このオプションを選択すると、データ・ソースとのインタラクションが最小限で済むため、最高のパフォーマンスが得られます。 |
| 更新のみを遅延 | 挿入または削除操作が行われた場合は、変更内容をただちにデータベースに送信し、更新操作が行われた場合は、JTAトランザクションがコミットされるまで変更内容をデータ・ソースに送信しません。
このオプションは、一部のEJBコンテナ(OC4Jなど)との下位互換性が必要な場合に選択します。詳細は、16.2.3.1項「非遅延変更」を参照してください。 このオプションを選択すると、データ・ソースのトランザクションとロックが長く保持されるため参照整合性に問題が生じるおそれがあるので、注意してください。 |
| 遅延しない | すべての変更内容をただちにデータベースに送信します。このオプションを選択すると、データ・ソースとのインタラクションが最大級になるため、パフォーマンスは最低になります。
このオプションは、一部のEJBコンテナ(OC4Jなど)との下位互換性が必要な場合に選択します。詳細は、16.2.3.1項「非遅延変更」を参照してください。 |
| 次の後に新規オブジェクトを挿入 | 新規オブジェクトの挿入という変更内容を、Beanのライフ・サイクル・メソッドejbCreate(デフォルト)またはejbPostCreateの後にデータベースに送信します。このオプションは、変更を遅延させない場合にのみ選択します(119.30項「変更ポリシーの構成」を参照)。
|
Javaコードでは、ディスクリプタを使用してコンテナ管理の永続性を備えたエンティティBean(119.18.2.1項「CMP情報の構成」を参照)またはBean管理の永続性を備えたエンティティBean(119.18.2.2項「BMP情報の構成」を参照)の特性を定義できます。
ディスクリプタにCMP固有の情報を構成するには、次のようにCMPPolicyを定義します。
descriptor.setCMPPolicy(new CMPPolicy());
次のCMPPolicy APIを使用すると、Enterprise Beanのオプション動作を構成できます。
|
注意: これらのオプションの大半は、他のCMP実装との互換性のために提供されています。これらを使用するとアプリケーションのパフォーマンスが低下するため、選択に当たっては注意してください。 |
setDeferModificationsUntilCommit: デフォルトでは、すべての変更内容のデータベースへの送信は、トランザクションがコミットされるまで遅延させます。このメソッドを使用すると、各EJB操作の後、次のいずれかの遅延レベルでデータベースが更新されます。
CMPPolicy.NONE: デフォルトの動作です。
CMPPolicy.UPDATE_MODIFICATIONS: 各EJB操作の後、更新変更が行われた場合にのみ、データベースが更新されます。
CMPPolicy.ALL_MODIFICATIONS: 各EJB操作の後、あらゆる変更に対して、データベースが更新されます。
setNonDeferredCreateTime: 非遅延書込みを使用する場合に(「setDeferModificationsUntilCommit」を参照)、このメソッドを使用して、新規Enterprise Beanを、ejbPostCreateメソッドの前(CMPPolicy.AFTER_EJBCREATE)または後(CMPPolicy.AFTER_EJBPOSTCREATE)に挿入するようにTopLinkを構成します。
setForceUpdate: TopLinkが、アクセスされたすべてのEnterprise Beanを変更の有無に関係なくデータベースに書き込むようにします。
setUpdateAllFields: 変更されたフィールドのみを更新するのでなく、Beanのすべてのフィールドを強制的に更新するようにTopLinkを構成します。
setPessimisticLockingPolicy: EJBレベルのペシミスティック・ロックを構成します。
BMPディスクリプタは、BMPWrapperPolicyを使用して構成する必要があります。現在、Oracle JDeveloperもTopLink WorkbenchもBMPWrapperPolicyの定義をサポートしていないため、Javaコードを使用して定義する必要があります。
詳細は、119.32項「ラッパー・ポリシーの構成」を参照してください。
継承階層をマッピングすると、デフォルトでは、ルート・クラスまたはブランチ・クラスに対する問合せにより、ルート・クラスのインスタンスおよびそのサブクラスが返されます。
このデフォルト設定を使用するかわりに、ルート・クラスまたはブランチ・クラスのディスクリプタを構成して、次のことを実行できます。
ルート・クラスまたはブランチ・クラスへの問合せ時にサブクラスが含まれないようにします。
ルート・クラスまたはブランチ・クラスへの問合せ時にサブクラスを外部結合させます。
さらに、データベース・ビューを指定することでサブクラスの読取りを最適化することもできます。ビューは、複数の表にわたるサブクラスを持つルートまたはブランチ・クラスへの問合せを最適化するために使用できます。ビューは、すべてのサブクラス表に対して外部結合または和集合を適用したものである必要があります。
このオプションはリーフ・クラスには構成できません。
表119-20では、どのディスクリプタが問合せでのサブクラス読取り機能の構成をサポートしているかを示します。
表119-20 ディスクリプタでの問合せでのサブクラス読取り機能構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した問合せでのサブクラス読取り機能の構成方法 |
Javaを使用した問合せでのサブクラス読取り機能の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
![]() |
|
XMLディスクリプタ |
|
![]() |
![]() |
詳細は、16.2.2項「ディスクリプタと継承」を参照してください。
副問合せでのクラスの読取りを構成するには、次の手順に従います。
ナビゲータで、ルートまたはブランチのディスクリプタを選択します。
そのディスクリプタに対して「継承」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「継承」を選択します。
次の情報を参照し、タブの「問合せでのサブクラスの読取り」および「サブクラス読取り用のビュー(オプション)」フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| 問合せでのサブクラスの読取り | ルート・クラスへの問合せ時にサブクラスがインスタンス化されるようにルート・クラス・ディスクリプタを構成します。 |
| サブクラス読取り用のビュー(オプション) | 必要に応じ、サブクラスの読取りに使用するデータベース・ビューを選択します。 |
| すべてのサブクラスの外部結合 | 必要に応じて、outerJoinAllSubclssesオプションを使用して問合せを最適化します。 |
ルートまたはブランチ・クラス・ディスクリプタのInheritancePolicyをカスタマイズするためのディスクリプタ修正メソッドを作成します(119.35項「修正メソッドの構成」を参照)。
例119-9は、Personクラスの修正メソッドを示します。この例では、InheritancePolicyメソッドdontReadSubclassesOnQueriesを使用してディスクリプタを構成しているため、問合せでサブクラスの読取りが行われません。
例119-9 問合せでのサブクラス読取り機能の構成
...
public static void addToPersonDescriptor(Descriptor descriptor) {
descriptor.getInheritancePolicy().dontReadSubclassesOnQueries();
}
...
例119-10は、Personクラスの修正メソッドを示します。この例では、InheritancePolicyメソッドsetReadAllSubclassesViewNameを使用して、複数の表にわたる継承についての問合せを最適化しています。
例119-10 ビュー名を使用した問合せでのサブクラス読取り機能の構成
...
public static void addToPersonDescriptor(Descriptor descriptor) {
descriptor.getInheritancePolicy().setReadAllSubclassesViewName(myView);
}
...
例119-11は、Personクラスの修正メソッドを示します。この例では、InheritancePolicyメソッドsetShouldOuterJoinSubclassesを使用してディスクリプタを構成しているため、問合せでサブクラスが外部結合されます。
継承とは、導出されたクラス(子)にそのスーパークラス(親)の特性をどのように受け継がせるかということを意味します。あるクラスを子として定義する場合は、継承階層内でその親を示すディスクリプタを指定する必要があります。
表119-21では、どのディスクリプタが子の継承構成をサポートしているかを示します。
表119-21 ディスクリプタでの子の継承構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した子(ブランチまたはリーフ)クラス・ディスクリプタに関する継承の構成方法 |
Javaを使用した子(ブランチまたはリーフ)クラス・ディスクリプタに関する継承の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
![]() |
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
|
|
|
継承の詳細は、16.2.2項「ディスクリプタと継承」を参照してください。
親(ルート)クラス・ディスクリプタに関する継承の構成方法の詳細は、119.21項「親(ルート)ディスクリプタに関する継承の構成」を参照してください。
継承を行う子(ブランチまたはリーフ・クラス)を作成するには、次の手順を実行します。
ナビゲータで、子として指定するディスクリプタを選択します。
プロパティ・ウィンドウで「継承」タブを選択します。
「継承」タブが表示されない場合は、ディスクリプタを右クリックして「アドバンスト・プロパティの選択」→「継承」を選択します。
「子ディスクリプタ」オプションを選択し、このディスクリプタを子クラスとして指定します。「親ディスクリプタ」リストがアクティブになり、クラス・インジケータ情報が非アクティブ化されます。
次の情報を参照し、タブの子ディスクリプタの各フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| 子ディスクリプタ | このディスクリプタを、ブランチまたはリーフとして使用する子クラスとして指定します。 |
| 親ディスクリプタ | ドロップダウン・リストから、このディスクリプタの親を選択します。詳細は、16.2.2項「ディスクリプタと継承」を参照してください。 |
Javaでは、例119-12のようにInheritancePolicyメソッドsetParentClassを使用して、継承先の子ディスクリプタを構成できます。
継承とは、導出されたクラス(子)にそのスーパークラス(親)の特性をどのように受け継がせるかということを意味します。あるクラスを親として定義する際に、そのクラスの継承階層をTopLinkで処理する方法を構成できます。
表119-22では、どのディスクリプタが親の継承構成をサポートしているかを示します。
表119-22 ディスクリプタでの親の継承構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した親(ルート)ディスクリプタに関する継承の構成方法 |
Javaを使用した親(ルート)ディスクリプタに関する継承の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
|
|
|
子(ブランチまたはリーフ)クラス・ディスクリプタに関する継承の構成方法の詳細は、119.20項「子(ブランチまたはリーフ)クラス・ディスクリプタに関する継承の構成」を参照してください。
詳細は、16.2.2項「ディスクリプタと継承」を参照してください。
継承を行うルート・クラスを作成するには、次の手順を実行します。
ナビゲータで、ルートとして指定するディスクリプタを選択します。
プロパティ・ウィンドウで「継承」タブを選択します。
「継承」タブが表示されない場合は、ディスクリプタを右クリックして「アドバンスト・プロパティの選択」→「継承」を選択します。
「ルートの親ディスクリプタ」オプションを選択し、このディスクリプタをルート・クラスとして指定します。
次の表を参照し、「継承」タブにある次のルート・ディスクリプタ関連フィールドを指定します。
| フィールド | 説明 |
|---|---|
| ルートの親ディスクリプタ | 選択したディスクリプタを継承階層のルート(親)として指定します。 |
| クラス抽出メソッドの使用 | このオプションを選択すると、ドロップダウン・リストからstaticクラス抽出メソッドを選択でき、クラス抽出メソッドによってクラス・インジケータを指定できます。
詳細は、16.3.1.2項「クラス抽出メソッドの使用」を参照してください。 |
| クラス・インジケータ・フィールドの使用 | このオプションを選択すると、クラス・インジケータ・フィールドを使用してクラス・インジケータを指定できます。
詳細は、16.3.1.1項「クラス・インジケータ・フィールドの使用」を参照してください。 |
| フィールド選択 | クラス・インジケータ・フィールドとして使用するフィールドを選択します。 |
| XMLスキーマの"type"属性を使用脚注1 | XMLスキーマに指定されているtype属性を、このディスクリプタの参照クラス用に使用します。 |
| フィールドの指定 | リレーショナル・ディスクリプタの場合は、ディスクリプタに関連付けられているデータベース表のフィールドを選択します(23.2項「関連表の構成」を参照)。
EISルート・ディスクリプタ(XMLレコードを使用)またはXMLディスクリプタの場合は、「参照」をクリックして、いずれかの要素属性またはテキスト・ノードを選択します。 |
| インジケータ選択 | クラス名をクラス・インジケータ・フィールドとして使用するか、各(非抽象)子クラス用に特定のクラス・インジケータ・フィールド値を指定します。 |
| インジケータとしてのクラス名の使用 | クラス名をクラス・インジケータ・フィールド値として使用します。 |
| クラス・インジケータ・ディクショナリの使用 | このオプションを選択すると、各(非抽象)子クラス用に特定のクラス・インジケータ・フィールド値を指定できます。
このオプションを選択する場合は、各(非抽象)子クラス用に、クラス・インジケータ・フィールドのデータ・タイプおよび値を指定する必要があります。 |
| インジケータ・タイプ | ドロップダウン・リストから、クラス・インジケータ・フィールドのデータ・タイプとして指定するデータ・タイプを選択します。
各(非抽象)子クラスに特定のクラス・インジケータ・フィールド値を指定するには、「編集」をクリックして、各子クラスに適切な値を入力します。 |
脚注1 EISルート・ディスクリプタ(75.2.1.1項「EISルート・ディスクリプタ」を参照)またはXMLディスクリプタ(50.1項「XMLディスクリプタの概念」を参照)のみ。
ルート・クラス・ディスクリプタの継承ポリシーをカスタマイズするためのディスクリプタ修正メソッドを作成し(119.35項「修正メソッドの構成」を参照)、そのメソッド内で、InheritancePolicyのメソッドsetParentClass、setClassIndicatorFieldName、addClassIndicator、useClassNameAsIndicatorおよびsetClassExtractionMethodNameを必要に応じて使用します。
例119-15は、PersonおよびStudentクラスの修正メソッドを示します。このStudentクラスは、Personをリレーショナル・プロジェクト用に拡張したものです。この例では、クラス・インジケータ・フィールドが使用されています(16.3.1.1項「クラス・インジケータ・フィールドの使用」を参照)。
例119-13 リレーショナル・ルート・クラスに関する継承の構成
...
public static void addToPersonDescriptor(Descriptor descriptor) {
descriptor.getInheritancePolicy().setClassIndicatorFieldName("CLIENT_TYPE");
descriptor.getInheritancePolicy().addClassIndicator(Student.class, indicator);
}
public static void addToStudentDescriptor(Descriptor descriptor) {
descriptor.getInheritancePolicy().setParentClass(Person.class);
...
}
...
クラス抽出メソッド(16.3.1.2項「クラス抽出メソッドの使用」を参照)を使用する場合は、InheritancePolicyメソッドsetOnlyInstancesExpressionおよびsetWithAllSubclassesExpressionの使用が必要な場合があります(119.22項「親(ルート)クラス・ディスクリプタに関する継承式の構成」を参照)。
例119-15は、PersonおよびStudentクラスの修正メソッドを示します。このStudentクラスは、Personクラスを、XMLレコードを使用するEISプロジェクト用に拡張したものです。この例では、クラス・インジケータ・フィールドが使用されています(16.3.1.1項「クラス・インジケータ・フィールドの使用」を参照)。
例119-14 EISルート・クラスに関する継承の構成
...
public static void addToPersonDescriptor(Descriptor descriptor) {
descriptor.getInheritancePolicy().setClassIndicatorField(
new XMLField("@CLIENT_TYPE"));
descriptor.getInheritancePolicy().addClassIndicator(Student.class, indicator);
}
public static void addToStudentDescriptor(Descriptor descriptor) {
descriptor.getInheritancePolicy().setParentClass(Person.class);
descriptor.getInheritancePolicy().setClassIndicatorField(
new XMLField("@CLIENT_TYPE")
);
}
...
クラス抽出メソッドを使用して(16.3.1.2項「クラス抽出メソッドの使用」を参照)クラスで継承を使用する場合は(16.3項「ディスクリプタと継承」を参照)、共通の表を使用するすべてのクラスの兄弟インスタンスを正しくフィルタ処理するための式を、TopLinkに指定する必要があります。
表119-23では、どのディスクリプタが継承式の構成をサポートしているかを示します。
表119-23 ディスクリプタでの継承式の構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchの使用方法 | Javaを使用した親(ルート)クラス・ディスクリプタに関する継承式の構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
![]() |
![]() |
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
![]() |
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
図119-34は、典型的な継承階層を示します。この例では、PersonおよびStudentの両クラスのインスタンスは、図119-35に示すPERSONという同じ表に格納されています。ただし、Personのインスタンスでは、STUDENT_NUMBERの値がnullになっています。Companyのインスタンスは別の表COMPANYに格納されています。
PersonとStudentのように、同一の表を共有する継承クラスへの問合せでは、それらの兄弟インスタンスをフィルタ処理する必要があります。TopLinkは、ディスクリプタのInheritancePolicyのメソッドgetOnlyInstancesExpressionおよびgetWithAllSubclassesExpressionによって返されるExpressionインスタンスを使用して、このフィルタ処理を実行します。
兄弟クラスとの共有でない固有の表を特定のデータ用に持つクラス(Companyなど)への問合せには、このような式は不要です。
クラスのインジケータ・タイプ・フィールドを使用する場合は(16.3.1.1項「クラス・インジケータ・フィールドの使用」を参照)、必要な式がTopLinkによって自動生成されます。
クラス抽出メソッドを使用する場合は(16.3.1.2項「クラス抽出メソッドの使用」を参照)、共通の表を使用するすべてのクラスの兄弟インスタンスを正しくフィルタ処理するための式を、TopLinkに指定する必要があります。
具象クラスの場合は、OnlyInstancesExpressionを定義する必要があります。
ブランチ・クラスの場合は、WithAllSubclassesExpressionを定義する必要があります。
TopLinkによるリーフ・クラスへの問合せでは、OnlyInstancesExpressionを使用して兄弟クラスがフィルタ処理されます。
固有の表が定義されていないサブクラスを持つルートまたはブランチ・クラスへの問合せでは、WithAllSubclassesExpressionが使用されます。これは、サブクラス・ビューを使用する場合も同様です(119.19項「問合せでのサブクラス読取り機能の構成」を参照)。
複数の表にわたるサブクラスを持つルートまたはブランチ・クラスへの問合せは、継承階層内の具象クラスごとに実行され、OnlyInstancesExpressionによって兄弟クラスがフィルタ処理されます。
クラス抽出メソッドを使用した場合は、OnlyInstancesExpressionによってクラスが具象クラスかどうかが判別されます。OnlyInstancesExpressionを必要としないクラスの場合は、問合せでのサブクラスの読取りを有効にしないでください(119.19項「問合せでのサブクラス読取り機能の構成」を参照)。有効にすると、TopLinkはそのクラスにインスタンスがないものとみなし、問合せでそのクラスをスキップします。
継承式の詳細は、16.3.1.2.1項「OnlyInstancesExpressionとWithAllSubclassesExpressionの指定」を参照してください。
ルート・クラス・ディスクリプタのInheritancePolicyをカスタマイズするためのディスクリプタ修正メソッドを作成し(119.35項「修正メソッドの構成」を参照)、そのメソッド内で、必要に応じてInheritancePolicyのメソッドsetOnlyInstancesExpressionおよびsetWithAllSubclassesExpressionを使用します。
例119-15は、図119-34に示したクラス階層と図119-35に示したデータベース表を使用するPersonおよびStudentディスクリプタに対する、修正メソッドを示します。
例119-15 OnlyInstancesExpressionの構成
... // Only-instances expression for Person public static void addToPersonDescriptor(Descriptor descriptor) { ExpressionBuilder builder = new ExpressionBuilder(); descriptor.getInheritancePolicy().setOnlyInstancesExpression( builder.getField("STUDENT_NUMBER").isNull()); } // Only-instances expression for Student public static void addToStudentDescriptor(Descriptor descriptor) { ExpressionBuilder builder = new ExpressionBuilder(); descriptor.getInheritancePolicy().setOnlyInstancesExpression( builder.getField("STUDENT_NUMBER").notNull()); } ...
例119-16は、図16-1に示したVehicle階層でそのすべてのクラスが単一のVehicle表に格納され、クラス・インジケータのかわりにクラス抽出メソッドが使用される場合に、このクラス階層に含まれるBicycleおよびNonFueledVehicleディスクリプタに対する修正メソッドを示します。
例119-16 OnlyInstancesExpressionとWithAllSubclassesExpressionの構成
// Bicycle amemndment public static void addToBicycleDescriptor(Descriptor descriptor) { ExpressionBuilder builder = new ExpressionBuilder(); descriptor.getInheritancePolicy().setOnlyInstancesExpression( builder.getField("BICYCLE_DESCR").notNull()); } // NonFueldVehicle ammendment public static void addToNonFueledVehicleDescriptor(Descriptor descriptor) { ExpressionBuilder builder = new ExpressionBuilder(); descriptor.getInheritancePolicy().setWithAllSubclassesExpression( builder.getField("FUEL_TYPE").isNull()); }
別のクラスから属性を継承するクラス用のディスクリプタを定義する際には、それらの属性のマッピングを作成できます。スーパークラスにすでにマップされている属性を再マップした場合、新しいマッピングはサブクラスにのみ適用されます。その属性を継承するその他の兄弟クラスは、影響を受けません。
継承属性が未マップのときは、スーパークラスのディスクリプタが親ディスクリプタとして指定されている場合には、TopLinkはスーパークラスのマッピング(存在する場合)を使用します。
表119-24では、どのディスクリプタが継承属性マッピングの構成をサポートしているかを示します。
表119-24 ディスクリプタでの継承属性マッピング構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したサブクラスでの継承属性マッピングの構成方法 |
Javaを使用したサブクラスでの継承属性マッピングの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
|
|
|
詳細は、16.2.2項「ディスクリプタと継承」を参照してください。
継承属性をマップするには、次の手順を実行します。
ナビゲータで、ディスクリプタを右クリックし、コンテキスト・メニューから「継承された属性のマップ」→「<選択したクラス>」を選択するか、メニューから「選択」→「継承された属性のマップ」を選択します。
マッピングのリストに、選択したクラスのスーパークラスからのすべての属性が表示されます。
必要な属性をすべてマップします。詳細は、第120章「マッピングの作成」を参照してください。
Javaを使用すると、スーパークラスからサブクラスに継承された属性を参照でき、それらの継承属性へのマッピングを随時作成できます。
ドメイン・オブジェクト・メソッドは、表119-26に示すどのディスクリプタ・イベントにも関連付けることができます。次の条件を満たす任意のドメイン・オブジェクト・メソッドを登録できます。
publicであること
voidを返すこと
タイプDescriptorEventの単一パラメータをとること
表119-25では、どのディスクリプタがドメイン・オブジェクト・メソッドによるイベント・ハンドラ構成をサポートしているかを示します。
表119-25 ディスクリプタでのドメイン・オブジェクト・メソッドによるイベント・ハンドラ構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したイベント・ハンドラとしてのドメイン・オブジェクト・メソッドの構成方法 |
Javaを使用したイベント・ハンドラとしてのドメイン・オブジェクト・メソッドの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
たとえば、メソッドhandlePostDelete(publicで、voidを返し、タイプDescriptorEventの単一パラメータをとる)をEmployeeオブジェクトに追加して、PostDeleteEventディスクリプタ・イベントを処理することができます。このメソッドを、Employeeオブジェクトのディスクリプタが所有するDescriptorEventManagerに、PostDeleteEventディスクリプタ・イベントのハンドラとして登録すると、Oracle TopLinkランタイムでは、Employeeオブジェクトのインスタンスに対する削除後操作が実行されるたびに、PostDeleteEventに関連付けられているEmployeeオブジェクトのインスタンスのhandlePostDeleteメソッドに対し、PostDeleteEventがディスパッチされます。
表119-26の「ディスクリプタ・イベントID」列は、特定のイベントを識別するための、DescriptorEventManagerのフィールド名を示します。DescriptorEventメソッドgetEventCodeは、これらのIDを値として返します。次に例を示します。
if (descriptorEvent.getEventCode() == DescriptorEventManager.PreUpdateEvent) {
// descriptorEvent represents a pre-update event
}
表119-26 ディスクリプタ・イベント
| カテゴリ | ディスクリプタ・イベントID | 説明 |
|---|---|---|
|
削除 |
|
データ・ソースからオブジェクトが削除される前に発生します。 |
|
|
データ・ソースからオブジェクトが削除される際に発生します。 |
|
|
|
データ・ソースからオブジェクトが削除された後に発生します。 |
|
|
挿入 |
|
データ・ソースにオブジェクトが挿入される前に発生します。 |
|
|
データ・ソースにオブジェクトが挿入される際に発生します。 |
|
|
|
データ・ソースにオブジェクトが挿入された後に発生します。 |
|
|
Post-X |
|
データ・ソースからオブジェクトが作成された後に発生します。 |
|
|
作業ユニットにオブジェクトがクローンされた後に発生します。 |
|
|
|
作業ユニットからオブジェクトがマージされた後に発生します。 |
|
|
|
データ・ソースからオブジェクトがリフレッシュされた後に発生します。 |
|
|
更新 |
|
データ・ソースでオブジェクトが更新される前に発生します。オブジェクトに変更がなく、更新が不要な場合でも、作業ユニット内でコールできます。 |
|
|
データ・ソースでオブジェクトが更新される際に発生します。作業ユニット内でオブジェクトが変更された場合のみコールされます。 |
|
|
|
データ・ソースでオブジェクトが更新された後に発生します。 |
|
|
書込み |
|
データ・ソースでオブジェクトが挿入または更新される前に発生します。これは、 |
|
|
データ・ソースでオブジェクトが挿入または更新された後に発生します。これは、 |
ドメイン・オブジェクト・メソッドのかわりに、ディスクリプタ・イベント・リスナーをイベント・ハンドラとして構成することもできます(119.25項「イベント・ハンドラとしてのディスクリプタ・イベント・リスナーの構成」を参照)。
イベント・メソッドを選択するには、次の手順を実行します。
ナビゲータでディスクリプタを選択します。そのプロパティがエディタに表示されます。
そのディスクリプタに対して「イベント」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「イベント」を選択します。
エディタで「イベント」タブをクリックします。
左側のリストから、適切なメソッド・カテゴリを選択します。
次の表に説明されている各フィールドで、適切なドメイン・オブジェクト・メソッドを選択します。
| カテゴリ | オプション | 説明 |
|---|---|---|
| 削除メソッド | 前 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースから削除される前に、そのインスタンスに対して起動されます。 |
| 後 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースから削除された後に、そのインスタンスに対して起動されます。 | |
| 挿入メソッド | 前 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースに挿入される前に、そのインスタンスに対して起動されます。 |
| 直前 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースに挿入される際に、そのインスタンスに対して起動されます。 | |
| 後 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースに挿入された後に、そのインスタンスに対して起動されます。 | |
| Post-Xメソッド | 作成 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースから作成された後に、そのインスタンスに対して起動されます。 |
| クローン | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスが作業ユニット内へクローン化された後に、そのインスタンスに対して起動されます。 | |
| マージ | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスが作業ユニットからマージされた後に、そのインスタンスに対して起動されます。 | |
| リフレッシュ | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースによってリフレッシュされた後に、そのインスタンスに対して起動されます。 | |
| 更新メソッド | 前 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースで更新される前に、そのインスタンスに対して起動されます。オブジェクトに変更がなく、更新が不要な場合でも、作業ユニット内でコールできます。 |
| 直前 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースで更新される際に、そのインスタンスに対して起動されます。作業ユニット内でオブジェクトが変更された場合のみコールされます。 | |
| 後 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースで更新された後に、そのインスタンスに対して起動されます。 | |
| 書込みメソッド | 前 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースで挿入または更新される前に、そのインスタンスに対して起動されます。
注意: これは、 |
| 後 | ここで選択したドメイン・オブジェクト・メソッドは、その参照クラスのインスタンスがデータ・ソースで挿入または更新された後に、そのインスタンスに対して起動されます。
注意: これは、PostInsertEventおよびPostUpdateEventメソッドが起動された後に発生します。 |
例119-17は、PostDeleteEventディスクリプタ・イベントを処理するためのhandlePostDeleteメソッドが定義されたドメイン・オブジェクト・クラスを示します。例119-18は、このメソッドをPostDeleteEventイベント・ハンドラとして登録する方法を示します。TopLinkランタイムでは、Employeeのインスタンスに対する削除後操作が実行されるたびに、Employeeオブジェクトのディスクリプタに所有されているDescriptorEventManagerに対し、PostDeleteEventがディスパッチされます。すると、DescriptorEventManagerは、そのPostDeleteEventに関連付けられているEmployeeのインスタンスに対してhandlePostDeleteメソッドを起動します。
独自のDescriptorEventListnerを作成して、ディスクリプタ修正メソッド内のDescriptorEventManagerに登録できます。また、Javaイベント・モデルを使用してイベントが通知されるようにDescriptorEventListnerを構成できます。
ドメイン・オブジェクトのディスクリプタが所有する、任意のディスクリプタ・イベント・タイプ(表119-28を参照)の処理が可能なDescriptorEventManagerに、DescriptorEventListenerインタフェースを実装した任意のオブジェクトを登録できます。このインタフェースの簡単な実装方法として、抽象クラスDescriptorEventAdapterを拡張し、目的のイベントに関するメソッドのみをオーバーライドできます。
表119-27では、どのディスクリプタがディスクリプタ・イベント・リスナーの構成をサポートしているかを示します。
表119-27 ディスクリプタでのディスクリプタ・イベント・リスナーの構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したイベント・ハンドラとしてのディスクリプタ・イベント・リスナーの構成方法 |
Javaを使用したイベント・ハンドラとしてのディスクリプタ・イベント・リスナーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
たとえば、Employeeオブジェクトに関するPostBuildEventディスクリプタ・イベントを処理するためにDescriptorEventListenerを作成したとします。このDescriptorEventListenerをEmployeeオブジェクトのディスクリプタが所有するDescriptorEventManagerに登録すると、TopLinkランタイムでは、Employeeのインスタンスに対する作成後操作が実行されるたびに、イベント・リスナーのpostBuildメソッドにPostBuildEventがディスパッチされます。
表119-28は、各ディスクリプタ・イベントに関連付けられているDescriptorEventListenerメソッドを示します。各ディスクリプタ・イベントに関連付けられているDescriptorEventListenerメソッドは、「ディスクリプタ・イベント・リスナー・メソッド」列に示されています。
表119-28 ディスクリプタ・イベント
| カテゴリ | ディスクリプタ・イベント・リスナー・メソッド | 説明 |
|---|---|---|
|
削除 |
|
データ・ソースからオブジェクトが削除される前に発生します。 |
|
|
データ・ソースからオブジェクトが削除される際に発生します。 |
|
|
|
データ・ソースからオブジェクトが削除された後に発生します。 |
|
|
挿入 |
|
データ・ソースにオブジェクトが挿入される前に発生します。 |
|
|
データ・ソースにオブジェクトが挿入される際に発生します。 |
|
|
|
データ・ソースにオブジェクトが挿入された後に発生します。 |
|
|
Post-X |
|
データ・ソースからオブジェクトが作成された後に発生します。 |
|
|
作業ユニットにオブジェクトがクローンされた後に発生します。 |
|
|
|
作業ユニットからオブジェクトがマージされた後に発生します。 |
|
|
|
データ・ソースからオブジェクトがリフレッシュされた後に発生します。 |
|
|
更新 |
|
データ・ソースでオブジェクトが更新される前に発生します。オブジェクトに変更がなく、更新が不要な場合でも、作業ユニット内でコールできます。 |
|
|
データ・ソースでオブジェクトが更新される際に発生します。作業ユニット内でオブジェクトが変更された場合のみコールされます。 |
|
|
|
データ・ソースでオブジェクトが更新された後に発生します。 |
|
|
書込み |
|
データ・ソースでオブジェクトが挿入または更新される前に発生します。これは、 |
|
|
データ・ソースでオブジェクトが挿入または更新された後に発生します。これは、 |
ディスクリプタ・イベント・リスナー・メソッドのかわりに、ドメイン・オブジェクト・メソッドをイベント・ハンドラとして構成することもできます(119.24項「イベント・ハンドラとしてのドメイン・オブジェクト・メソッドの構成」を参照)。
詳細は、119.24.1項「TopLink Workbenchを使用したイベント・ハンドラとしてのドメイン・オブジェクト・メソッドの構成方法」を参照してください。
例119-19は、PostBuildEventディスクリプタ・イベントを処理するDescriptorEventListenerを示します。例119-20は、このDescriptorEventListenerをEmployeeオブジェクトのディスクリプタに登録する方法を示します。TopLinkランタイムでは、Employeeのインスタンスに対する作成後操作が実行されるたびに、登録済の各イベント・リスナーの適切なDescriptorEventListenerメソッド(この例ではpostBuild)に対し、作成後イベントがディスパッチされます。
ロック・ポリシーを使用してディスクリプタを構成すると、ユーザーが別のユーザーの作業内容を上書きするのを防ぐことができます。
表119-29では、どのディスクリプタがロック・ポリシーをサポートしているかを示します。
表119-29 ディスクリプタでのロック・ポリシーのサポート
| ディスクリプタ | オプティミスティック・バージョン・ロック・ポリシー |
オプティミスティック・フィールド・ロック・ポリシー |
ペシミスティック・ロック・ポリシー |
Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したロック・ポリシーの構成方法 |
Javaを使用したロック・ポリシーの構成方法 |
|---|---|---|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
|
|
|
EISディスクリプタ脚注2 |
|
|
|
|
|
|
|
XMLディスクリプタ |
|
|
|
|
|
|
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
ロック・ポリシーを使用することをお薦めします。マルチユーザー環境では、あるユーザーが別のユーザーの変更内容を上書きするのを防ぐために、ロック・ポリシーを使用する必要があります。ロック機能は、特に、複数のサーバーまたは複数のアプリケーションが同一データにアクセスする場合に重要ですが、シングル・サーバー・アプリケーションにおいても、ロック上の同じ問題は依然として存在しています。マルチサーバー環境においては、アプリケーションがキャッシュ・リフレッシュやキャッシュ・コーディネーションを使用している場合であっても、やはりロック機能は必要です。
3層アプリケーションを構築する場合は、オブジェクトが正しくロックされるようにするため、そのオブジェクトが編集用にクライアントに送信される前にロックを取得できるようにする必要があります。それを実現するための方法は、選択するロックのタイプによって異なります(16.4.6項「3層アプリケーションでのロック」を参照)。
ディスクリプタのロック・ポリシーを指定するには、次の手順を実行します。
ナビゲータで、リレーショナル・ディスクリプタまたはEISルート・ディスクリプタを選択します。
そのディスクリプタに対して「ロック」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「ロック」を選択します。
「ロック」タブをクリックします。
次の表に説明されている、該当するディスクリプタ・タイプのタブの各フィールドに、データを指定します。
| フィールド | 説明 |
|---|---|
| オプティミスティック・ロック | このディスクリプタにオプティミスティック・ロックを使用することを指定します。 |
| バージョン | バージョニングに基づいたオプティミスティック・ロックを使用することを指定します。 |
| データベース・フィールド | オプティミスティック・ロックに使用するバージョン値を含むデータベース・フィールドを選択します。
このフィールドは、リレーショナル・ディスクリプタの場合にのみ表示されます。 |
| XPath | 「参照」をクリックして、バージョン値を格納する要素または属性までのパスを指定します。
このフィールドは、EISルート・ディスクリプタの場合にのみ表示されます。 属性のタイプが、選択するロック・ポリシーのタイプに対応していることを確認してください(「バージョンのロック」の場合は |
| バージョンのロック | 数値によるバージョンのロックをこのディスクリプタに使用することを指定します。バージョン・フィールド(リレーショナル・ディスクリプタの場合は「データベース・フィールド」、EISルート・ディスクリプタの場合は「XPath」)は、numericタイプである必要があります。 |
| タイムスタンプ・ロック | タイム・スタンプを使用した、タイム・スタンプ・バージョンのロックを、このディスクリプタに使用することを指定します。バージョン・フィールド(リレーショナル・ディスクリプタの場合は「データベース・フィールド」、EISルート・ディスクリプタの場合は「XPath」)は、timestampタイプである必要があります。 |
| キャッシュにバージョンを保存 | バージョン情報をキャッシュに格納するかどうかを指定します。
バージョン・フィールドにマッピングを指定しない場合は、バージョン値がOracle TopLinkのキャッシュに格納されるようにディスクリプタを構成するため、必ずこのオプションを選択してください。 バージョン・フィールドにマッピングを指定する場合は、このオプションの選択を解除して、バージョン値がオブジェクトに格納されるようにします。 詳細は、16.4.6.1項「3層アプリケーションでのオプティミスティック・ロック」を参照してください。 |
| フィールド脚注1 | データベース・フィールドに基づいてオプティミスティック・ロックを使用することを指定します。
データベース・フィールドは、リレーショナル・ディスクリプタの場合にのみ表示されます。 |
| すべてのフィールド | すべてのデータベース・フィールドにオプティミスティック・ロックを適用します。 |
| 変更されたフィールド | 変更されたデータベース・フィールドにのみオプティミスティック・ロックを適用します。 |
| 選択されたフィールド | 「追加」をクリックして選択した特定のデータベース・フィールドにのみ、オプティミスティック・ロックを適用します。 |
| ペシミスティック・ロック | ペシミスティック・ロックをこのディスクリプタに使用することを指定します。
これは、EJB CMP情報が構成されているディスクリプタにのみ適用されます(119.18項「EJB CMPおよびBMP情報によるディスクリプタの構成」を参照)。 |
| ロックを待機 | TopLinkがデータ・ソースのロックを待機するかどうかを指定します。このチェック・ボックスを選択しない場合、実行スレッドがオブジェクトに対する読取りロックを取得できないと、ただちにDatabaseExceptionがスローされます。
このチェック・ボックスを選択した場合、実行スレッドは読取りロックが解放されるまで無期限に待機してから、読取りロックの取得を試みます。このオプションの使用は、アプリケーションのデッドロックを招く場合があるため注意が必要です。 |
脚注1 フィールド・ロックをAttributeChangeTrackingPolicyと併用することはできません(113.2.3.3項「属性変更追跡ポリシー」を参照)。
この項の内容は次のとおりです。
必要なオプティミスティック・フィールド・ロック・ポリシーのインスタンスを設定するには、ClassDescriptorメソッドsetOptimisticLockingPolicyを使用します。
AllFieldsLockingPolicy
ChangedFieldsLockingPolicy
SelectedFieldsLockingPolicy
VersionLockingPolicy
TimestampLockingPolicy
選択したロック・ポリシー・タイプを取得して構成するには、ClassDescriptorメソッドgetOptimisticLockingPolicyを使用します。
VersionLockingPolicyを使用している場合は、カスケード機能を有効化すると、親オブジェクトが私有する子オブジェクトのバージョン・フィールドが変更された場合に、その親オブジェクトのバージョン・フィールドが強制的に自動更新されるようにTopLinkを構成できます。カスケード機能を有効化するには、VersionLockingPolicyメソッドsetIsCascadedをブール値true付きで使用し、無効化するにはfalse付きで使用します。
詳細は、16.4.2項「オプティミスティック・バージョン・ロック・ポリシーとカスケード」を参照してください。
CMPPolicyを使用している場合にかぎり、PessimisticLockingPolicyを使用してディスクリプタを構成できます。つまり、PessimisticLockingPolicyを構成できるのは、CMPプロジェクト内でEJB CMP情報をサポートしているディスクリプタのみです(119.18項「EJB CMPおよびBMP情報によるディスクリプタの構成」を参照)。
PessimisticLockingPolicyのインスタンスを設定するには、CMPPolicyをインスタンス化してCMPPolicyメソッドsetPessimisticLockingPolicyを使用します。次に、ClassDescriptorメソッドsetCMPPolicyを使用して、CMPPolicyを設定します。
リターン・ポリシーを使用すると、オブジェクトの挿入または更新時にデータ・ソースからフィールド値を取得できます。TopLinkでは、データ・ソースから返されたこの値を使用して、それらのフィールドにマップされているオブジェクト属性が更新されます。挿入および更新用の値を返させるフィールドは、指定できます。挿入フィールドについては、フィールド値を挿入操作の対象として含めるかどうかも指定できます。
リターン・ポリシーは、デフォルト、トリガーまたはストアド・プロシージャによって、データ・ソースからデフォルトまたは初期のフィールド値を取得する場合に役立ちます。また、リターン・ポリシーを使用すると、データ・ソースから順序値または主キー値を割り当てることもできます。
ディスクリプタのリターン・ポリシー内に構成しなかったオブジェクト属性に対しては、デフォルトの動作が実行されます。作業ユニットのコンテキストにおいては、その属性が変更されると、属性の値がデータベースに書き込まれます。逆に、対象のデータベース・フィールドを変更するトリガーまたはストアド・プロシージャがSQL文によって起動された場合、データベースで生成された値はオブジェクトには反映されません。
リターン・ポリシーの使用は、挿入や更新のパフォーマンスを左右し、また、バッチ書込み(12.11.3項「バッチ書込みを使用した最適化方法」を参照)と併用できないため、使用の判断は慎重に行ってください。
デフォルトでは、リターン・ポリシーはOracleデータベースで使用できるようになっており、TopLinkではOracle RETURNING句が使用されます(119.27.1項「TopLink Workbenchを使用したリターン・ポリシーの構成方法」を参照)。
リターン・ポリシーをOracle以外のデータベースにも使用できるようにするには、必要な戻り値を出力パラメータとして返すストアド・プロシージャを使用するよう、ディスクリプタの挿入または更新問合せを構成します(119.27.2項「Javaを使用したリターン・ポリシーの構成方法」を参照)。
表119-30では、どのディスクリプタがリターン・ポリシーの構成をサポートしているかを示します。
表119-30 ディスクリプタでのリターン・ポリシーの構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したリターン・ポリシーの構成方法 |
Javaを使用したリターン・ポリシーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ脚注1 |
|
|
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
脚注1 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
ディスクリプタにリターン・ポリシーを指定するには、次の手順を実行します。
ナビゲータでディスクリプタを選択します。そのプロパティがエディタに表示されます。
そのディスクリプタに対して「戻り値」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「戻り値」を選択します。
エディタで「戻り値」タブをクリックします。
次の情報を参照し、タブの各フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| 挿入 | この領域のオプションは挿入操作に適用されます。 |
| 名前 | 「追加」をクリックして、挿入操作のリターン・ポリシー用にデータベース・フィールドを追加できます。 |
| 戻り値のみ | 選択した場合、TopLinkはそのフィールドの値のみを返し、フィールドを挿入の対象には含めません。
選択しなかった場合、TopLinkはそのフィールドの値を返すのみでなく、その値の挿入も行います。 |
| 更新 | この領域のオプションは更新操作に適用されます。 |
| 名前 | 「追加」をクリックして、更新操作のリターン・ポリシー用にデータベース・フィールドを追加できます。 |
データベース・フィールドをディスクリプタのリターン・ポリシーの対象から削除するには、「挿入」または更新・ウィンドウでデータベース・フィールドを選択して「削除」ボタンをクリックします。
|
注意: TopLink Workbenchの使用時には、トランスフォーメーション・マッピング(27.13項「トランスフォーメーション・マッピング」を参照)でマップされている属性についてはリターン・ポリシーを構成できません。 |
リターン・ポリシーを使用して、TopLinkがオブジェクト属性の戻り値を処理する方法をフィールドごとに構成できます。表119-31に、各データベース・フィールドの処理方法をTopLinkに指示するReturnPolicyメソッドについて説明します。各メソッドは、フィールド名としてStringまたはDatabaseFieldタイプのパラメータを取ります。
表119-31 ReturnPolicyメソッド
| メソッド | 適用先のSQL文のタイプ | データベースに現行フィールド値を書き込むか | データベース生成結果を返すか |
|---|---|---|---|
|
|
INSERT |
○ |
○ |
|
|
INSERT |
× |
○ |
|
|
UPDATE |
○ |
○ |
ディスクリプタにリターン・ポリシーを構成するには、ClassDescriptorメソッドsetReturningPolicyを使用します。
TopLinkランタイムでは、クラスのディスクリプタに構成したインスタンス化ポリシーに従って、そのクラスの新規インスタンスが作成されます。
表119-32では、どのディスクリプタがインスタンス化ポリシーをサポートしているかを示します。
表119-32 ディスクリプタでのインスタンス化ポリシーのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したインスタンス化ポリシーの構成方法 |
Javaを使用したインスタンス化ポリシーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
|
|
|
次のいずれかのタイプのインスタンス化ポリシーを指定できます。
デフォルト: クラスのデフォルト・コンストラクタをコールすることにより、そのクラスの新規インスタンスが作成されます。
メソッド: クラス・ディスクリプタに定義したpublicのstaticメソッドをコールすることにより、そのクラスの新規インスタンスが作成されます。
ファクトリ: ファクトリ設計パターンに従って実装したクラスごとの適切なメソッドをコールすることにより、そのクラスの新規インスタンスが作成されます。
ディスクリプタにインスタンス化ポリシーを設定するには、次の手順を実行します。
ナビゲータで、ディスクリプタを選択します。
そのディスクリプタに対して「インスタンス化」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「インスタンス化」を選択します。
次の情報を参照し、タブの各フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| デフォルト・コンストラクタの使用 | クラスのデフォルト・コンストラクタで新規インスタンスを作成する場合に選択します。 |
| メソッドの使用 | データベースからオブジェクトを作成するために実行するメソッドを指定します。 |
|
データベースからオブジェクトを作成するために実行するメソッドの名前を選択します。このメソッドは、ディスクリプタのクラスのpublicのstaticメソッドであり、オブジェクトの新規インスタンスを返すものである必要があります。 |
| ファクトリの使用 | オブジェクト・ファクトリ・メソッドを指定します。 |
| ファクトリ・クラス | 新規インスタンスを作成するファクトリ・オブジェクトのクラスを選択します。 |
| ファクトリ・メソッド | ファクトリ・オブジェクトを取得するためのメソッドを選択します。デフォルト・コンストラクタを使用するには、「<指定なし>」を選択します。 |
| インスタンス作成メソッド | データ・ソースからのデータが移入される新規インスタンスを取得するために、ファクトリ・オブジェクトに対してコールされるメソッドを選択します。 |
該当するタイプのインスタンス化ポリシーを設定するには、次のいずれかのClassDescriptorメソッドを使用します。
useDefaultConstructorInstantiationPolicy
useMethodInstantiationPolicy
useFactoryInstantiationPolicy
TopLinkの作業ユニットの機能は、永続オブジェクトの完全なコピー(クローン)を作成できるように構成しておく必要があります。表119-33では、どのディスクリプタがコピー・ポリシーをサポートしているかを示します。
表119-33 コピー・ポリシーによるディスクリプタの構成
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用したコピー・ポリシーの構成方法 |
Javaを使用したコピー・ポリシーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
|
EISディスクリプタ |
|
|
|
|
XMLディスクリプタ |
|
|
|
TopLinkでは、次の2種類の方法でオブジェクトをコピーできます。
インスタンス化ポリシー: デフォルトでは、現在構成されているインスタンス化ポリシーに従って、オブジェクトの新しいコピーが作成されます(119.28項「インスタンス化ポリシーの構成」を参照)。
メソッド: オブジェクトに指定したメソッドをコールすることにより、そのオブジェクトの新しいコピーが作成されます。たとえば、オブジェクトのクローン・メソッド(または、そのオブジェクトにあるその他の適切なメソッド)を指定できます。cloneメソッドは、オブジェクトのシャロー・クローンを返します。
ディスクリプタにコピー・ポリシーを指定するには、次の手順を実行します。
ナビゲータでディスクリプタを選択します。そのプロパティがエディタに表示されます。
ディスクリプタに対して「コピー」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「コピー」を選択します。
エディタで「コピー」タブをクリックします。
次の情報を参照し、タブの各フィールドにデータを入力します。
| フィールド | 説明 |
|---|---|
| インスタンス化ポリシーの使用 | ディスクリプタのインスタンス化ポリシーに従って、オブジェクトの新規インスタンスが作成されます(119.28項「インスタンス化ポリシーの構成」を参照)。 |
| クローン・メソッドの使用 | オブジェクトのクローン・メソッドをコールするかどうかを指定します。メソッドは、リストから選択してください。 |
該当するタイプのコピー・ポリシーを設定するには、次のいずれかのClassDescriptorメソッドを使用します。
useCloneCopyPolicy(): オブジェクトにクローン・メソッドがあることが必要です。
useCloneCopyPolicy(java.lang.String cloneMethodName)
useInstantiationCopyPolicy()
変更ポリシーを使用すると、作業ユニットに登録後のオブジェクトに加えられる変更を、TopLinkでどのように追跡するかを指定できます。表119-34では、どのディスクリプタが変更ポリシーをサポートしているかを示します。
表119-34 ディスクリプタでの変更ポリシーのサポート
| ディスクリプタ | 遅延変更検出ポリシー |
オブジェクト・レベル変更追跡ポリシー |
属性変更追跡ポリシー |
Oracle JDeveloperの使用方法 | TopLink Workbenchの使用方法 | Javaを使用した変更ポリシーの構成方法 |
|---|---|---|---|---|---|---|
|
リレーショナル・ディスクリプタ脚注1 |
|
|
|
![]() |
![]() |
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
|
|
![]() |
![]() |
|
|
EISディスクリプタ脚注2 |
|
|
|
![]() |
![]() |
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
脚注1 リレーショナル・クラス・ディスクリプタのみ(22.2.1.1項「リレーショナル・クラス・ディスクリプタの作成」を参照)。
脚注2 EISルート・ディスクリプタのみ(75.2.1.1項「EISルート・ディスクリプタ」を参照)。
デフォルトでは、遅延変更検出ポリシーが使用されます。
ウィービング用に構成したJPAエンティティまたはPOJOクラスの場合、TopLinkでは、1対1マッピングのValueHolderインダイレクションのウィービングが実行されます。アプリケーションにコレクション・マッピング(1対多または多対多)が含まれている場合にTopLinkで変更追跡に対するウィービングが実行されるようにするには、すべてのコレクション・マッピングに対し、透過インダイレクト・コンテナ・インダイレクションのみが使用されるように構成する必要があります(コレクション・マッピングは、即時ロードやValueHolderインダイレクションが使用されるようには構成できません)。
可変基本マッピングは、変更追跡のオーバーヘッドに影響を与えます。TopLinkがウィービングを実行できるのは、不変マッピングの属性変更追跡ポリシーのみです。
変更ポリシーをサポートしないディスクリプタのウィービングを実行しようとすると、TopLinkではCONFIGログ・レベルで警告メッセージが記録されます。
TopLinkでサポートされるマッピングのサブセットを使用する属性については、その他の変更ポリシー(DeferredChangeDetectionPolicy以外のポリシー)が用意されています。
OC4J TopLinkにデプロイされたCMPおよびJPAアプリケーションについては、属性変更追跡ポリシーが自動的に使用されます。
詳細は、次を参照してください。
『EclipseLink Developer's Guide』の「Using EclipseLink JPA Weaving」(http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Weaving)
この項では、Javaを使用してディスクリプタに変更ポリシーを構成する方法、および介入型の変更ポリシー用に永続クラスを実装する方法について説明します。この項では、次のような構成方法について説明します。
DeferredChangeDetectionPolicyを使用すると、広範なオブジェクト変更特性に関して、作業ユニットのコミットで良好なパフォーマンスが得られます。これはデフォルトの変更ポリシーです。詳細は、113.2.3.1項「遅延変更検出ポリシー」を参照してください。
このポリシーはデフォルトのため、明示的に構成する必要はありません。
DeferredChangeDetectionPolicyが使用されるようにTopLinkを構成するには、例119-21のように、この変更ポリシーを設定するディスクリプタ修正メソッドを作成します(119.35項「修正メソッドの構成」を参照)。
ObjectChangeTrackingPolicyを使用すると、わずかな属性のみを持つオブジェクトや、多数の属性を持ち、しかも変更される属性が多いオブジェクトに関して、作業ユニットのコミットのパフォーマンスが向上します。詳細は、113.2.3.2項「オブジェクト・レベル変更追跡ポリシー」を参照してください。
TopLinkによってCMP統合が提供されているアプリケーション・サーバー(8.1項「アプリケーション・サーバーのサポートの概要」を参照)にデプロイされたCMPおよびJPAアプリケーションの場合、ObjectLevelChangeTrackingPolicyを使用してエンティティBeanのディスクリプタを構成すると、TopLink ChangeTrackerインタフェースを実装するための具象サブクラスのコードがデプロイ時に自動生成されます。ObjectLevelChangeTrackingPolicyを構成すると、AttributeChangeTrackingPolicy(119.30.1.3項「属性変更追跡ポリシーの構成」を参照)がTopLinkによって自動適用されるのを防止できます。
ObjectChangeTrackingPolicyが使用されるようにTopLinkを構成するには、次の手順を実行します。
例119-21のように、この変更ポリシーを設定するディスクリプタ修正メソッドを作成します(119.35項「修正メソッドの構成」を参照)。
プレーンJavaオブジェクトの場合、例119-22のように、ChangeTrackerインタフェースを実装するための各永続クラスのコードを記述します。
例119-22 ChangeTrackerインタフェースのObjectChangeTrackingPolicy用の実装
public class Employee implements ChangeTracker {
PropertyChangeListener listener;
String firstName;
public PropertyChangeListener getTopLinkPropertyChangeListener() {
return this.listener;
}
public void setTopLinkPropertyChangeListener(PropertyChangeListener listener) {
this.listener = listener;
}
...
public void setFirstName(String firstName) {
propertyChange("firstName", getFirstName(), firstName);
this.firstName = firstName;
}
...
public void propertyChange(String propertyName, Object oldValue, Object newValue) {
if (listener != null) {
if (oldValue != newValue) {
listener.propertyChange(
new PropertyChangeEvent(this, propertyName, oldValue, newValue));
}
}
}
}
The AttributeChangeTrackingPolicyを使用すると、多数の属性を持つが変更される属性が少ないオブジェクトに関する作業ユニットの、コミットのパフォーマンスが向上します。通常は、この変更ポリシーを取ると、最も高いパフォーマンスが得られます。これが、OC4JにデプロイされたJPAおよびEJB 2.n CMPアプリケーションにおけるデフォルトの変更ポリシーです。詳細は、113.2.3.3項「属性変更追跡ポリシー」を参照してください。
|
注意: FieldsLockingPolicyのインスタンスを使用している場合(16.4.4項「オプティミスティック・フィールド・ロック・ポリシー」を参照)、AttributeChangeTrackingPolicyは使用できません。 |
TopLink対応のEJB 3.0永続アプリケーションまたはEJB 2.n CMPアプリケーションをOC4Jにデプロイすると、TopLinkはAttributeChangeTrackingPolicyを使用するように永続クラスを自動構成し、さらにバイトコードのウィービング(EJB 3.0の場合)またはコード生成(EJB 2.nの場合)によって永続クラスを構成して、TopLink ChangeTrackerインタフェースを実装します。この場合は、この変更ポリシーを明示的に構成する必要がありません。
プレーンJavaオブジェクトまたはその他のアプリケーション・サーバーでAttributeChangeTrackingPolicyが使用されるようにTopLinkを構成するには、次の手順を実行します。
例119-23のように、この変更ポリシーを設定するディスクリプタ修正メソッドを作成します(119.35項「修正メソッドの構成」を参照)。
例119-24のように、ChangeTrackerインタフェースを実装するための各永続クラスのコードを記述します。
例119-24 ChangeTrackerインタフェースのAttributeChangeTrackingPolicy用の実装
public class Employee implements ChangeTracker {
PropertyChangeListener listener;
String firstName;
public PropertyChangeListener getTopLinkPropertyChangeListener() {
return this.listener;
}
public void setTopLinkPropertyChangeListener(PropertyChangeListener listener) {
this.listener = listener;
}
...
public void setFirstName(String firstName) {
propertyChange("firstName", getFirstName(), firstName);
this.firstName = firstName;
}
...
public void propertyChange(String propertyName, Object oldValue, Object newValue) {
if (listener != null) {
if (oldValue != newValue) {
listener.propertyChange(
new PropertyChangeEvent(this, propertyName, oldValue, newValue));
}
}
}
}
独自に設計した履歴スキーマに対して履歴問合せを実行するために(108.11項「履歴問合せ」を参照)履歴セッションを使用する必要がある場合は(87.6項「履歴セッション」を参照)、その履歴スキーマを記述したTopLink HistoryPolicyを使用してディスクリプタを構成します。
Oracle9i Database以上に対してOracle Databaseプラットフォームを使用している場合は、履歴ポリシーを構成しなくても、Oracle Databaseによって自動的に保持されるオブジェクトの履歴バージョンを問い合せることができます。詳細は、93.1.1項「Oracleプラットフォームを使用した履歴セッションの構成方法」を参照してください。
表119-35では、どのディスクリプタが履歴ポリシーの構成をサポートしているかを示します。
表119-35 ディスクリプタでの履歴ポリシーの構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchの使用方法 | Javaを使用した履歴ポリシーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
![]() |
![]() |
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
![]() |
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
履歴データベース・スキーマを構成する方法は数多くあります。TopLinkでは、HistoryPolicyを使用して定義できる様々な履歴スキーマ構成がサポートされています(87.6.1項「履歴セッションの制限事項」を参照)。
履歴スキーマの例
表119-36および表119-37に示すように、一般的な方法の1つは、オブジェクトの履歴バージョンを格納するための特別な履歴表、つまり、永続的な履歴を必要とする通常の表ごとに1つの履歴表を定義する方法です。履歴表では、通常、対応する通常の表と同じフィールドを設けるとともに、特定バージョンの存続期間を示す時間隔を定義するフィールド(行の開始(ROW_START)、行の終了(ROW_END)フィールドなど)を作成します。
|
注意: TopLinkでは、オブジェクトの現行バージョンは、行の終了フィールドがNULLである履歴表の行に相当するとみなしています。 |
履歴問合せを実行すると、HistoryPolicyに定義された履歴表がTopLinkに読み取られます。
表119-36は、EMPLOYEE表のスキーマを示します。この表には現在EMPLOYEEインスタンスが含まれています。
表119-37は、従業員の履歴バージョンを格納するEMPLOYEE_HISTという履歴表の例を示します。この表には、EMPLOYEEの現行バージョン(ROW_ENDの値がNULLのバージョン)と、履歴バージョン(1件)が含まれています。
表119-37 履歴表EMPLOYEE_HISTの例
| EMP_ID | F_NAME | L_NAME | SALARY | ROW_START | ROW_END |
|---|---|---|---|---|---|
|
1 |
Jane |
Doe |
50000 |
29/08/2004 |
31/08/2004 |
|
1 |
Jane |
Doe |
55000 |
31/08/2004 |
NULL |
すべてのレコードには開始および終了時間隔が含まれるため、履歴表には同一オブジェクトの(同じ主キーを持つ)複数のバージョンを格納できます。特定バージョンに対する一意の識別子は、既存の主キーとROW_STARTフィールドの値を組み合せて割り当てられます。たとえば、表119-37の場合、最新バージョンを示す一意の識別子は(EMP_ID, START) = (1, 31/08/2004)となります。
例119-25は、表119-36および表119-37で示したスキーマを、TopLink HistoryPolicyによって記述する方法を示します。
例119-25 単一の表に対するHistoryPolicy
HistoryPolicy policy = new HistoryPolicy();
policy.addStartFieldName("ROW_START");
policy.addEndFieldName("ROW_END");
policy.addHistoryTableName("EMPLOYEE", "EMPLOYEE_HIST");
// Assuming database triggers or stored procedures update history tables
policy.setShouldHandleWrites(false);
employeeDescriptor.setHistoryPolicy(policy);
例119-26に示すように、同一のHistoryPolicyに複数の表を指定することもできます。この例では、すべての履歴表にROW_STARTという開始フィールドがありますが、終了フィールドはEMPLOYEE_HIST表とSALARY_HIST表の間で異なっています。曖昧性を排除するため、終了フィールド名の先頭にはそれぞれの履歴表名が追加されています。
例119-26 複数の表に対するHistoryPolicy
HistoryPolicy policy = new HistoryPolicy();
policy.addStartFieldName("ROW_START");
policy.addEndFieldName("EMPLOYEE_HIST.ROW_END");
policy.addEndFieldName("SALARY_HIST.VALID_UNTIL");
policy.addHistoryTableName("EMPLOYEE", "EMPLOYEE_HIST");
policy.addHistoryTableName("SALARY", "SALARY_HIST");
// Assuming database triggers or stored procedures update history tables
policy.setShouldHandleWrites(false);
employeeDescriptor.setHistoryPolicy(policy);
TopLinkでは、ユーザーに表示されるクラスと永続クラスが異なる場合にラッパー(またはプロキシ)を使用できます。
たとえば、3.0より前のEJB仕様では、エンティティBeanクラス(javax.ejb.EntityBeanを実装するクラス)は永続クラスですが、javax.ejb.EJBObjectを実装するクラス(ローカルまたはリモートのインタフェース・クラス)と対話するユーザーには表示されません。この例では、EJBObjectはEntityBeanのプロキシ(またはラッパー)として動作します。
このようなラッパーを使用した場合、TopLinkはディスクリプタに指定されているクラスを常に永続クラスとみなしますが、永続オブジェクトがリクエストされると必ずラッパーの適切なインスタンスを返します。
表119-38では、どのディスクリプタがラッパー・ポリシーをサポートしているかを示します。
表119-38 ディスクリプタでのラッパー・ポリシーのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchの使用方法 | Javaを使用したラッパー・ポリシーの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
![]() |
![]() |
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
|
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
ラッパー・ポリシーを使用すると、特定の永続クラスのラッパーをどのように作成し、特定のラッパー・インスタンスから基礎となる永続オブジェクトをどのように取得するかを、TopLinkに指示することができます。
ラッパー・ポリシーを指定すると、TopLinkはそのポリシーに基づき、永続オブジェクトを必要に応じてラップまたはアンラップします。
ラッパー・ポリシーはインタフェースoracle.toplink.descriptors.WrapperPolicyを実装します。
ラッパー・ポリシーを指定するには、TopLinkディスクリプタにそのラッパー・ポリシーを設定します。
デフォルトでは、ラッパー・ポリシーは使用されません(ディスクリプタのラッパー・ポリシーはデフォルトでNULLに設定されています)。
|
注意: ラッパー・ポリシーは高度なTopLinkオプションです。ラッパー・ポリシーの使用は、TopLink Workbenchの一部の機能とは併用できない場合があります。 |
CMPディスクリプタの場合は、EJBラッパー・ポリシーはデプロイ時に自動的に構成されるため、ディスクリプタに設定する必要はありません(119.18項「EJB CMPおよびBMP情報によるディスクリプタの構成」を参照)。
BMPディスクリプタについては、BMPWrapperPolicyをディスクリプタに設定する必要があります。BMPWrapperPolicyには、bean-name、primary-key-class、home-interface、remote-interfaceなど、Beanの情報が含まれます。
ラッパー・ポリシーはOracle JDeveloperまたはTopLink Workbenchでは設定できません。Javaコードを使用する方法でのみ設定できます(119.32.1項「Javaを使用したラッパー・ポリシーの構成方法」を参照)。
WrapperPolicyの適切なインスタンスを設定するには、ClassDescriptorメソッドsetWrapperPolicyを使用します。
例119-27は、必要なBMP情報を使用してBMPディスクリプタを修正する方法を示します。
デフォルトでは、特定のオブジェクト・クラスに対してオブジェクト・レベルの読取り問合せを実行すると、そのオブジェクトのディスクリプタにマップされているすべての永続属性がTopLinkによって返されます。この1回の問合せを実行するだけで、対象オブジェクトのすべての永続属性が定義され、さらに、各属性のgetメソッドをコールすることで、属性値をオブジェクトから直接取得できます。
オブジェクトの属性の一部のみが必要な場合は、フェッチ・グループを使用して、そのオブジェクトの属性のサブセットのみが返されるようにした方が効率的です。
フェッチ・グループを使用して、オブジェクトの属性のサブセットを定義し、そのフェッチ・グループをReadObjectQueryまたはReadAllQuery問合せと関連付けることができます。問合せを実行すると、TopLinkによりフェッチ・グループ内の属性のみが取得されます。除外された属性のいずれかに関するgetメソッドをコールすると、TopLinkでは、このサブセットから除外されたすべての属性をフェッチする問合せが自動的に実行されます。
1つのクラスに対して複数のフェッチ・グループを定義できます。必要であれば、最大1つのフェッチ・グループをデフォルトのフェッチ・グループとして指定できます。フェッチ・グループを指定せずにReadObjectQueryまたはReadAllQueryを実行すると、デフォルトのフェッチ・グループが使用されます。ただし、デフォルトのフェッチ・グループを指定しないように問合せを構成した場合は除きます(111.3.1項「フェッチ・グループのデフォルト動作の構成方法」を参照)。
フェッチ・グループは、EJBオブジェクト用のCMPまたはJPAプロジェクトのみでなく、POJOクラスにも使用できます。
フェッチ・グループを使用する前に、システムの使用状況を綿密に分析しておくことをお薦めします。多くの事例では、フェッチ・グループに含まれない属性をロードするために必要な追加の問合せにより、部分的な属性のロードによって得られるメリットがかなり相殺されているためです。読取りパフォーマンスの最適化の詳細は、12.12.9項「読取り最適化の例」を参照してください。
表119-39では、どのディスクリプタがフェッチ・グループの構成をサポートしているかを示します。
表119-39 ディスクリプタでのフェッチ・グループの構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchの使用方法 | Javaを使用したフェッチ・グループの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
![]() |
![]() |
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
|
|
EISディスクリプタ |
![]() |
![]() |
![]() |
|
XMLディスクリプタ |
![]() |
![]() |
![]() |
ウィービング用に構成したJPAエンティティまたはPOJOクラスの場合、TopLinkではフェッチ・グループを使用してパフォーマンスを向上させます。
この項では、フェッチ・グループの作成およびディスクリプタへの格納、およびそのディスクリプタ参照クラスのデフォルトのフェッチ・グループとしての指定(オプション)の方法を説明します。
詳細は、次を参照してください。
『EclipseLink Developer's Guide』の「Using EclipseLink JPA Weaving」(http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Weaving)
フェッチ・グループを構成するには、例119-28に示すように、ディスクリプタ修正メソッドを使用します(119.35項「修正メソッドの構成」を参照)。
例119-28 フェッチ・グループの構成
//Create a FetchGroupManager for the descriptor descriptor.setFetchGroupManager(new FetchGroupManager()); // Create a FetchGroup FetchGroup group = new FetchGroup("nameOnly"); // Add attributes to FetchGroup. Alternatively, use // FetchGroup method addAttributes, passing in a Set of String attribute names group.addAttribute("firstName"); group.addAttribute("lastName"); // Add the FetchGroup to the FetchGroupManager descriptor.getFetchGroupManager().addFetchGroup(group); //Set the default fetch group descriptor.getFetchGroupManager().setDefaultFetchGroup(group);
ディスクリプタ内に格納するFetchGroupの各インスタンスは、そのディスクリプタで一意のフェッチ・グループ名を使用して構成する必要があります(各ディスクリプタは複数の名前付きフェッチ・グループのセットを所有しているため)。
フェッチ・グループを構成する場合は、主キー・フィールドとその他の必要なフィールド(継承タイプ、オプティミスティック・ロックのバージョンなど)をすべてのフェッチ・グループに必ず含めてください。フェッチ・グループには直接属性とリレーションシップ属性を含めることができます。フェッチ・グループにリレーションシップ属性を含めても、そのリレーションシップは結合もインスタンス化もされません。結合およびインダイレクションは、フェッチ・グループとは別に設定します。
フェッチ・グループをディスクリプタに追加した後は、そのフェッチ・グループを名前で指定(nameOnly)してReadObjectQueryまたはReadAllQuery問合せを構成したり、そのフェッチ・グループをデフォルトでTopLinkに使用させることができます。詳細は、111.3項「問合せでのフェッチ・グループの使用」を参照してください。
ディスクリプタ・カスタマイザ・クラスはJavaクラスで、oracle.toplink.tools.sessionconfiguration.DescriptorCustomizerインタフェースを実装し、デフォルト(ゼロ引数)コンストラクタを備えています。ディスクリプタ・カスタマイザを使用すると、ログインが行われる前にロード済だったセッションに基づいて、別のディスクリプタを実行時にカスタマイズできます。その方法は修正メソッドを使用する方法と似ています(119.35項「修正メソッドの構成」を参照)。
表119-40では、どのセッションがカスタマイザ・クラスの構成をサポートしているかを示します。
表119-40 ディスクリプタでのカスタマイザ・クラス構成のサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchの使用方法 | Javaを使用したカスタマイザ・クラスの構成方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
![]() |
|
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
|
![]() |
|
|
EISディスクリプタ |
|
![]() |
|
|
XMLディスクリプタ |
|
![]() |
|
詳細は、16.2.6項「ディスクリプタのカスタマイズ」を参照してください。
Javaを使用する場合は、oracle.toplink.tools.sessionconfiguration.DescriptorCustomizerインタフェースを実装するカスタマイザ・クラスを作成します。例119-29は、ディスクリプタ・カスタマイザの作成を示します。
例119-29 SessionCustomizerクラスの作成
import oracle.toplink.tools.sessionconfiguration.DescriptorCustomizer;
import oracle.toplink.descriptors.ClassDescriptor;
public class EmployeeDescriptorCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) {
descriptor.setReadOnly();
}
}
一部のTopLinkディスクリプタの機能は、Oracle JDeveloperまたはTopLink Workbenchからは構成できません。これらの機能を使用するには、ディスクリプタをプロジェクトの一部としてロードした後に修正するJavaメソッドを記述します。このメソッドは次の特性を備えている必要があります。
public staticである必要があります。
タイプoracle.toplink.descriptors.ClassDescriptorのパラメータを1つとる必要があります。
このメソッドの実装では、publicの任意のディスクリプタとマッピングAPIを使用して、ディスクリプタの高度な機能を構成できます。
表119-41では、どのディスクリプタが修正メソッドをサポートしているかを示します。
表119-41 ディスクリプタでの修正メソッドのサポート
| ディスクリプタ | Oracle JDeveloperの使用方法 | TopLink Workbenchを使用した修正メソッドの構成方法 |
Javaの使用方法 |
|---|---|---|---|
|
リレーショナル・ディスクリプタ |
|
|
![]() |
|
オブジェクト・リレーショナル・データ・タイプ・ディスクリプタ |
![]() |
![]() |
![]() |
|
EISディスクリプタ |
|
|
![]() |
|
XMLディスクリプタ |
|
|
![]() |
この項では、修正メソッドとディスクリプタを関連付ける方法について説明します。
修正メソッドの実装方法の詳細は、16.2.7項「修正メソッドとロード後メソッド」を参照してください。
あるいは、ディスクリプタ・カスタマイザ・クラスを使用できます(119.34項「ディスクリプタ・カスタマイザ・クラスの構成」を参照)。
セッションをカスタマイズするには、セッション・カスタマイザ・クラスを使用します(89.8項「セッション・カスタマイザ・クラスの構成」を参照)。
プロジェクトの一部としてロードした後のディスクリプタに修正メソッドを使用するには、次の手順を実行します。
ナビゲータでディスクリプタを選択します。そのプロパティがエディタに表示されます。
そのディスクリプタに対して「ロード後」アドバンスト・プロパティが表示されない場合は、ディスクリプタを右クリックして、コンテキスト・メニューまたは「選択」メニューから「アドバンスト・プロパティの選択」→「ロード後」を選択します。
| フィールド | 説明 |
|---|---|
| クラス | 「参照」をクリックし、実行するメソッドのクラスを選択します。 |
| Staticメソッド | 「Staticメソッド」のリストから、ディスクリプタのロード後に実行時に実行するStaticメソッドを選択します。このメソッドは、public staticであり、タイプoracle.toplink.descriptors.ClassDescriptorの属性を1つとるものである必要があります。 |