7 多相ビュー・オブジェクトの定義

この章では、ADFビジネス・コンポーネントの継承を使用して、Oracle ADFアプリケーションで複数のビュー行型を公開するADFビュー・オブジェクトを作成する方法を説明します。また、この章では、エンティティ・オブジェクトの継承を使用するかわりの方法として、ビュー・オブジェクトの継承階層を定義して異種ビュー行を生成する方法についても説明します。

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

多相ビュー・オブジェクトについて

ADFビジネス・コンポーネントを使用すると、継承階層から属性を継承したエンティティ・オブジェクトに基づいている多相ビュー・オブジェクトを操作できます。多相ビュー・オブジェクトでは、異種混在の行セットを保持します。

ビュー・オブジェクトでは、ベース・エンティティ・オブジェクトによって表現される表を作成できます。一般に、エンティティ・ベースのビュー・オブジェクトを作成するときには、Domestics(国内の顧客に関連する固有の属性を含むと考えられる)など、単一の型を持つエンティティ行を操作するようにビュー・オブジェクトを作成します。また、場合によっては、同じ行セットでエンティティ・オブジェクト継承階層に基づいて行を問い合せて更新することもあります。たとえば、同じ行セットで、CustomersDomesticsおよびInternationalsの各エンティティ・オブジェクトの継承階層に共通する属性を処理することがあります。ここで、DomesticsInternationalsは、親のCustomersエンティティ・オブジェクトのサブタイプ・エンティティ・オブジェクトです。このようなビュー・オブジェクトは多相ビュー・オブジェクトと呼ばれます。クライアントで多相ビュー・オブジェクトが適切に使用されるようにするために、ビュー・オブジェクトでは、異種混在の行セット内の各行について、委譲先のエンティティ・オブジェクトを認識しておく必要があります。行の型を識別するために、多相ビュー・オブジェクトは、各行の対応する表を特定する識別子属性に依存しています。

ADFビジネス・コンポーネントは、次のタイプのポリモフィズムをサポートします。

  • エンティティ・オブジェクトは多相サブタイプを定義しますが、ビュー・オブジェクトはしません。

    これは、バックエンド・ビジネス・ロジックは各種タイプを認識する必要があるが、プレゼンテーション・レイヤーはビュー・インスタンスを単一のタイプとみなす必要がある場合に役立ちます。この場合、ビュー・インスタンスは、エンティティ・サブタイプによって定義された各属性の共通のセットを含みます。

  • エンティティ・オブジェクトとビュー・オブジェクトの慣用名は、どちらも多相サブタイプを定義します。

    この場合、バックエンド・ビジネス・ロジックとプレゼンテーション・レイヤーは、どちらも各種サブタイプを区別する必要があります。

  • エンティティ・オブジェクトは多相サブタイプを定義しませんが、ビュー・オブジェクトの慣用名は多相サブタイプを定義します。

    この場合、プレゼンテーション・レイヤーはビュー・サブタイプを区別する必要がありますが、バックエンド・ビジネス・ロジックは一意ではありません。

多相ビュー・オブジェクト(エンティティ・サブタイプの継承に基づくもの)を作成する場合、クライアントに様々なエンティティ・サブタイプが公開されることはありません。クライアントが関係する範囲では、ビュー・オブジェクトの結果セットの各行は同じ属性セットと同じ行の型を持ちます。このようになるのは、ADFビジネス・コンポーネントによって、識別子属性の値に基づいて必ず正しいエンティティ・オブジェクト行サブタイプが作成されるようになっているからです。つまり、多相エンティティ・オブジェクトの慣用名を使用することで、ビュー行の型は一定でありながら、ビュー行のエンティティ行の部分でのみ型が変更できるようになっています。

一方、(エンティティ・サブタイプでなく)ビュー・オブジェクト階層によって定義される継承に基づいて多相ビュー・オブジェクトを作成する場合は、アプリケーション・モジュールを構成して、結果に1つ以上のビュー行サブタイプが存在するようにできます。クライアントに表示されるビュー行の型に異なる複数のサブタイプを生成できるのは、多相ビュー行を使用した場合のみです。また、多相エンティティ・オブジェクトの慣用名から派生したビュー・オブジェクトとは異なり、ビュー行のサブタイプに属性を追加してクライアントに公開できることも、多相ビュー行のみの特徴です。

ノート:

この章の概念を説明する例を試すには、「SummitADF_Examplesワークスペースからのスタンドアロン・サンプルの実行」.の説明に従ってSummitADF_Examplesワークスペースを使用します。Summit ADFスタンドアロン・サンプル・アプリケーションを取得およびインストールする方法の詳細は、「Oracle ADF用Summitサンプル・アプリケーションの設定」を参照してください。

多相エンティティ・オブジェクトの慣用名と多相ビュー行の慣用名

いずれかのタイプのポリモーフィズムを使用したり、2つを結合したりできます。

通常は一緒に使用する方が役に立ちますが、ビュー行ポリモーフィズム機能と多相エンティティ・オブジェクト慣用名機能は異なるものであり、個別に使用できます。特に、ビュー行ポリモーフィズムの機能は、読取り専用ビュー・オブジェクトにも、エンティティ・ベースのビュー・オブジェクトにも使用できます。両方のメカニズムを組み合せると、多相のエンティティ行部分とビュー行型の両方を持つことができます。

ビュー・オブジェクトまたはエンティティ・オブジェクトでビュー行ポリモーフィズムを使用するには、それぞれに個別の識別子属性プロパティを構成する必要があることに注意してください。これが必要になるのは、読取り専用ビュー・オブジェクトには、識別子情報を推測する関連エンティティ・オブジェクトの慣用名が含まれていないためです。

識別子属性が1レベルを超えない深さで定義されるビュー・オブジェクトを必要とする多相ビュー・オブジェクトの場合は、制限があります。プロジェクトで行のサブタイプを指定する識別子属性を持つ多相ビュー・オブジェクを定義する場合がありますが、このとき別のビュー・オブジェクトを使用して、最初の多相ビュー・オブジェクトに基づいてさらにサブ行を指定すると、サブ行の表示でエラーが発生します。多相ビュー・オブジェクトを作成する場合は、識別子属性の定義を1レベルに制限してください。

要約すると、多相エンティティ・オブジェクトの慣用名を含むビュー・オブジェクトを作成するには、次のことを行います。

  1. 継承階層のルート・エンティティ・オブジェクトのエンティティ・オブジェクト・レベルで、識別子にする属性を構成します。

  2. 継承されるエンティティ・オブジェクトの階層を定義し、階層内のエンティティ・オブジェクトのそれぞれでオーバーライドを行って、そのエンティティ・オブジェクト・レベルの識別子属性のサブタイプ値プロパティに個別の値を設定します。

  3. ビュー・オブジェクトのサブタイプのリストに、サブクラス化されたエンティティ・オブジェクトのリストを入れます。

  4. アプリケーション・モジュールを更新して、この階層のエンティティ・ベースのサブタイプ・ビュー・オブジェクトを、アプリケーション・モジュールのサブタイプのリストに公開します。

このため、ビュー行のポリモフィズムを使用する場合は、次の手順を実行します。

  1. 継承階層のベース・ビュー・オブジェクトのビュー・オブジェクト・レベルで、識別子にする属性を構成します。

  2. 継承されるビュー・オブジェクトの階層を定義し、階層内の各ビュー・オブジェクトのビュー・オブジェクト・レベルの識別子属性に、サブタイプ値プロパティとして個別値(ビュー・オブジェクト定義ファイルの属性のDefaultValueとして識別される)を指定します。

  3. アプリケーション・モジュールを更新して、この階層のサブクラス化されたサブタイプ・ビュー・オブジェクトを、アプリケーション・モジュールのサブタイプのリストに公開します。

多相エンティティ・オブジェクトの慣用名での作業

多相エンティティ慣用名を持つADFビュー・オブジェクトを使用して、ベース・エンティティ・オブジェクトとそのサブタイプに基づいて異種混在の行セットを作成できます。

多相エンティティ・オブジェクトの慣用名とは、継承階層のベース・エンティティ・オブジェクトを参照し、そのエンティティのサブタイプも処理するように構成されているものです。図7-1は、多相エンティティ・オブジェクトの慣用名でビュー・オブジェクトを使用した結果を示しています。エンティティ・ベースのCustomerListビュー・オブジェクトには、プライマリ・エンティティ・オブジェクトの慣用名としてCustomersエンティティ・オブジェクトがあります。ビュー・オブジェクトは、データベースから取得された各行を、Customersの様々なサブタイプに固有の属性を持つエンティティ行に分割します。識別子属性の値の検査に基づいて、適切なエンティティ行サブタイプを作成します。たとえば、CustomerListの問合せで、国内企業ABC Companyの1行と国際企業Simms Athleticsの1行が取得された場合、基礎になっているエンティティ行は図で示されているようになります。

図7-1 多相エンティティ・オブジェクトの慣用名を持つビュー・オブジェクトによるエンティティ・サブタイプの処理

図7-1の説明が続きます
「図7-1 多相エンティティ・オブジェクトの慣用名を持つビュー・オブジェクトによるエンティティ・サブタイプの処理」の説明

ノート:

この項の例では、SummitADF_Examplesアプリケーション・ワークスペースのoracle.summit.model.polymorphicパッケージを参照します。

多相エンティティ・オブジェクトの慣用名を持つサブタイプ・ビュー・オブジェクトを作成する方法

多相エンティティ・オブジェクトの慣用名で作成するビュー・オブジェクトは、ベース・エンティティ・オブジェクトおよびエンティティ・サブタイプの1つ以上の属性を継承できます。エンティティ・オブジェクトから選択する属性は、ビュー・オブジェクト属性定義によってオーバーライドされます。エンティティ・ベースのビュー・オブジェクトが識別子属性を持つエンティティ・オブジェクトを参照していると、Oracle ADFはその識別子属性も(主キー属性に加えて)問合せに含まれるようにします。

始める前に:

多相ビュー・オブジェクト(この項では、サブタイプ・ビュー・オブジェクトとも呼びます)について理解しておくと役立ちます。詳細は、「多相ビュー・オブジェクトについて」を参照してください。

次のタスクを完了する必要があります。

  1. ビュー・オブジェクトの基礎となるベース・エンティティ・オブジェクトおよびエンティティ・サブタイプを作成します。ベース・エンティティ・オブジェクトおよびエンティティ・サブタイプの作成の詳細は、「継承階層内にエンティティ・オブジェクトを作成する方法」を参照してください。

  2. ベース・エンティティ・オブジェクトからエンティティ・ベースのビュー・オブジェクトを作成し、サブタイプ・ビュー・オブジェクトに共通する属性を選択します。ベース・ビュー・オブジェクトは、各サブタイプ・ビュー・オブジェクトによって表される属性のスーパーセットを含む必要があります。エンティティ・ベースのビュー・オブジェクトの作成の詳細は、「エンティティ・ベースのビュー・オブジェクトの作成方法」を参照してください。

  3. 作成するベース・ビュー・オブジェクトで、作成する各サブタイプ・ビュー・オブジェクトに対応するエンティティ・サブタイプを選択します。JDeveloperは、作成予定の多相エンティティの慣用名セレクションに作成できるサブタイプ・ビュー・オブジェクトを制限します。

    ベース・ビュー・オブジェクトでエンティティ・サブタイプを選択するには:

    1. 概要エディタでベース・ビュー・オブジェクトを開き、「エンティティ・オブジェクト」ナビゲーション・タブをクリックします。

    2. 「エンティティ・オブジェクト」ページで「サブタイプ」をクリックし、「サブタイプの選択」ダイアログで、エンティティ・サブタイプを「選択済」リストに追加します。

    たとえば、図7-2に示すように、エンティティ・サブタイプDomesticsおよびInternationalsが、それぞれのサブタイプ・ビュー・オブジェクトの作成を予期して選択されています。

    図7-2 エンティティ・サブタイプによる、可能なサブタイプ・ビュー・オブジェクトの定義

    この図は周囲のテキストで説明しています

多相エンティティ・オブジェクトの慣用名でサブタイプ・ビュー・オブジェクトを作成するには:

  1. 「アプリケーション」ウィンドウでデータ・モデル・プロジェクトを右クリックし、「新規」「ビュー・オブジェクト」の順に選択します。

  2. 「ビュー・オブジェクトの作成」ウィザードで、サブタイプ・ビュー・オブジェクトの名前を指定し、「拡張」フィールドの横にある「参照」をクリックします。

    たとえば、サブタイプ・ビュー・オブジェクトがベース・ビュー・オブジェクトCustomerListを拡張する場合、サブタイプ・ビュー・オブジェクトにDomesticListまたはInternationalListを指定することがありえます。この場合、DomesticsInternationalsの各サブタイプ・エンティティ・オブジェクトの多相エンティティ・オブジェクト慣用名を使用したサブタイプ・ビュー・オブジェクト作成をサポートするために、データ・モデル・プロジェクトでベースのCustomersエンティティ・オブジェクトを定義できます。

  3. 「親の選択」ダイアログで、拡張するエンティティ・ベースのビュー・オブジェクトを選択して、「OK」をクリックします。

    選択したビュー・オブジェクトが、属性のスーパーセットを定義するベース・ビュー・オブジェクトであり、サブタイプ・ビュー・オブジェクトが拡張するビュー・オブジェクトです。たとえば、図7-3に示すように、サブタイプ・ビュー・オブジェクトDomesticListを作成する場合、拡張するベース・ビュー・オブジェクトCustomerListを選択します。

    図7-3 サブタイプ・ビュー・オブジェクトによるベース・ビュー・オブジェクトの拡張

    この図は周囲のテキストで説明しています
  4. ビュー・オブジェクト作成ウィザードで、データ・ソースとして「エンティティ」が選択されていることを確認して、「次へ」をクリックします。

  5. 「エンティティ・オブジェクト」ページの「使用可能」リストで、サブタイプ・ビュー・オブジェクトの多相エンティティの慣用名として定義するエンティティ・サブタイプを見つけ、「追加」をクリックします。

    この手順の前提条件で説明したように、使用できるエンティティ・サブタイプのリストはベース・エンティティ・オブジェクトの継承階層で定義されます。たとえば、ベース・ビュー・オブジェクトCustomerListのサブタイプ・ビュー・オブジェクトDomesticListを作成する場合、図7-4に示すように、「使用可能」リストから、エンティティ・サブタイプとしてDomesticsを追加します。

    図7-4 多相エンティティ・オブジェクトの慣用名が選択されたサブタイプ・ビュー・オブジェクト

    図7-4の説明が続きます
    「図7-4 多相エンティティ・オブジェクトの慣用名が選択されたサブタイプ・ビュー・オブジェクト」の説明
  6. 「ビジネス・コンポーネント」ダイアログで「はい」をクリックすると、目的の多相エンティティ・オブジェクトの慣用名で、サブタイプ・ビュー・オブジェクトのエンティティ・オブジェクトの慣用名をオーバーライドします。

    ビジネス・コンポーネント」ダイアログで、ベース・エンティティ・オブジェクトの慣用名の属性をエンティティ・サブタイプでオーバーライドする旨の警告が示されます(図7-5を参照)。

    ダイアログで「いいえ」をクリックすると、ベース・エンティティ・オブジェクト慣用名の属性をオーバーライドせずに、追加の慣用名が追加される点に注意してください。通常は、「はい」をクリックして、目的のエンティティ・サブタイプで、ベース・エンティティ・オブジェクトの慣用名をオーバーライドします。

    図7-5 多相エンティティ・オブジェクトの慣用名によるサブタイプ・ビュー・オブジェクトのオーバーライド

    この図は周囲のテキストで説明しています
  7. 「選択済」リストで、オーバーライドされたエンティティ・オブジェクト慣用名を選択して、「サブタイプ」をクリックします。

  8. 「サブタイプの選択」で、シャトル・ボタンを使用して「選択済」リストに目的の多相エンティティ・サブタイプのみを残して、「OK」をクリックします。

    「サブタイプの選択」ダイアログを使用すると、ビュー・オブジェクト作成ウィザードの「エンティティ・オブジェクト」ページで定義したオブジェクトの慣用名が参照するエンティティ・サブタイプを指定できます。この手順の前提条件で説明したように、使用できるエンティティ・サブタイプのリストはベース・オブジェクトにより定義されます。通常、オーバーライド対象として選択したものと同じエンティティ・サブタイプを選択します(図7-5参照)。

    たとえば、サブタイプ・ビュー・オブジェクトDomesticListを作成する場合、図7-6に示すように、ベース・エンティティ・オブジェクトCustomersの単一エンティティ・サブタイプとしてDomesticsを選択(および、「選択済」リストからInternationalsを選択解除)します。

    図7-6 単一の多相エンティティ・オブジェクトの慣用名が適用されたサブタイプ・ビュー・オブジェクト

    この図は周囲のテキストで説明しています
  9. ビュー・オブジェクトの作成ウィザードの「エンティティ・オブジェクト」ページで、「次へ」をクリックし、ウィザードの「属性」ページで必要な属性をエンティティ・サブタイプから「選択済」リストに移動します。

    たとえば、DomesticListビュー・オブジェクト用に、エンティティ・サブタイプDomesticsからState属性を選択します(図7-7を参照)。

    図7-7 エンティティ・サブタイプの属性が追加されたビュー・オブジェクト

    この図は周囲のテキストで説明しています
  10. 「属性」ページで、拡張されたビュー・オブジェクトが単一の主キー属性を定義するように主キー属性を削除し、次に識別子属性を選択して、「オーバーライド」をクリックし、「次へ」をクリックします。

    たとえば、DomesticListビュー・オブジェクトの場合、図7-8に示すように、サブタイプ・ビュー・オブジェクトの選択済リストからCountryId属性を削除して、CountryId属性をオーバーライドします。

    図7-8 オーバーライドされた識別子属性を持つビュー・オブジェクト

    図7-8の説明が続きます
    「図7-8 オーバーライドされた識別子属性を持つビュー・オブジェクト」の説明
  11. 「属性の選択」ページで、ドロップダウンから識別子属性を選択して、サブタイプを定義する「デフォルト値」を入力し、Finishをクリックしてウィザードを完了します。

    たとえば、DomesticListビュー・オブジェクトの場合、図7-9に示すように、DOMESTICと入力します。

    図7-9 オーバーライドされた識別子属性を持つビュー・オブジェクト

    図7-9の説明が続きます
    「図7-9 オーバーライドされた識別子属性を持つビュー・オブジェクト」の説明
  12. この手順を繰り返して、一意の多相エンティティ・オブジェクトの慣用名を持つ、追加のサブタイプ・ビュー・オブジェクトを作成します。

    たとえば、InternationalListビュー・オブジェクトは、CustomerListを拡張する2番目のサブタイプです。このオブジェクトでは、CustomerTypeCode識別子属性に値INTERNATIONALを設定しています。

サブタイプ・ビュー・オブジェクトを作成した後で、「サブタイプ・オブジェクトの慣用名を表示するためのアプリケーション・モジュールの更新」の説明に従い、ビュー・オブジェクト・ポリモフィズムに参加するサブタイプのリストを定義する必要があります。たとえば、ビュー・インスタンスCustomerList1を持つCustomersModuleアプリケーション・モジュールは、DomesticListおよびInternationalListの各サブタイプ・ビュー・オブジェクトを指定するように構成する必要があります。

多相エンティティ・オブジェクトの慣用名によりサブタイプ・ビュー・オブジェクトを作成すると行われる処理

概要エディタの「エンティティ・オブジェクト」ページに、選択されたエンティティ・オブジェクトとエンティティ・オブジェクト慣用名オーバーライドが表示されます。たとえば、DomesticListビュー・オブジェクトの概要エディタに、Customers (Domestics): overriddenのように、オーバーライドされたエンティティ・オブジェクト慣用名とカッコで囲まれたオーバーライドするサブタイプが表示されます(図7-10を参照)。

図7-10 ビュー・オブジェクト・エディタでのエンティティ・オブジェクトの慣用名のオーバーライド

この図は周囲のテキストで説明しています

多相エンティティ・オブジェクトの慣用名でエンティティ・ベースのビュー・オブジェクトを作成すると、JDeveloperにより、許可されるエンティティ・サブタイプに関する情報がベース・ビュー・オブジェクトのXMLドキュメントに追加されます。たとえば、CustomerListビュー・オブジェクトを作成すると、許可されるサブタイプ・エンティティ・オブジェクトの名前が<AttrArray>タグに記録されます。XMLプロパティDiscrColumnは、CountryTypeCodeを、次のようなベース・ビュー・オブジェクトの多相識別子属性として識別します。

<ViewObject Name="CustomerList" ... >
  <EntityUsage
    Name="Customers"
    Entity="oracle.summit.model.polymorphics.entities.Customers" >
  </EntityUsage>
  <AttrArray Name="EntityImports">
    <Item Value="oracle.summit.model.polymorphic.entities.Domestics" />
    <Item Value="oracle.summit.model.polymorphic.entities.Internationals" />
  </AttrArray>
...
  <ViewAttribute
    Name="CountryTypeCode"
    PrecisionRule="true"
    EntityAttrName="CountryTypeCode"
    EntityUsage="Customers"
    AliasName="COUNTRY_TYPE_CODE"
    DiscrColumn="true">
  </ViewAttribute>
   ...
</ViewObject>

こうして、多相エンティティ・オブジェクトの慣用名でサブタイプ・ビュー・オブジェクトを作成すると、JDeveloperにより、ベース・ビュー・オブジェクトに関する情報がサブタイプ・ビュー・オブジェクトのXMLドキュメントに追加されます。たとえば、次の例は、ベース・ビュー・オブジェクトの名前がExtendsプロパティ内に記録されたDomesticListサブタイプ・ビュー・オブジェクトを示しています。XMLプロパティDiscrColumnは、オーバーライドされたCountryTypeCode属性を、DOMESTICのサブタイプ値を持つ多相識別子属性として識別します。サブタイプ・ビュー・オブジェクトに固有の追加の属性Stateのみが、XMLドキュメントに表示されます。

<ViewObject
  Name="DomesticList"
  Extends="oracle.summit.model.polymorphic.views.CustomerList"
  ...>
  <EntityUsage
    Name="Customers"
    Entity="oracle.summit.model.polymorphic.entities.Domestics"/>
  <AttrArray Name="EntityImports">
    <Item Value="oracle.summit.model.polymorphicsample.Domestics"/>
  </AttrArray>
  <ViewAttribute
    Name="CountryTypeCode"
    PrecisionRule="true"
    DiscrColumn="true"
    EntityAttrName="CountryTypeCode"
    EntityUsage="Customers"
    AliasName="COUNTRY_TYPE_CODE"
    DefaultValue="DOMESTIC">
    <DesignTime>
      <Attr Name="_OverrideAttr" Value="true"/>
    </DesignTime>
  </ViewAttribute>
  <ViewAttribute
    Name="State"
    PrecisionRule="true"
    EntityAttrName="State"
    EntityUsage="Customers"
    AliasName="STATE"/>
</ViewObject>

同様に、次に示すように、InternationalListサブタイプ・ビュー・オブジェクトのXMLドキュメントでは、同じCustomerListベース・ビュー・オブジェクトの名前がそのXMLドキュメントのExtendsプロパティ内に指定されていますが、INTERNATIONALというサブタイプ値を持つ多相識別子属性と、そのサブタイプに固有の追加属性Languageが定義されています。

<ViewObject
  Name="InternationalList"
  Extends="oracle.summit.model.polymorphic.views.CustomerList"
  ... >
  <EntityUsage
     Name="Customers"
     Entity="oracle.summit.model.polymorphic.entities.Internationals"/>
  <AttrArray Name="EntityImports">
    <Item Value="oracle.summit.model.polymorphicsample.Internationals"/>
  </AttrArray>
  <ViewAttribute
    Name="CountryTypeCode"
    PrecisionRule="true"
    DiscrColumn="true"
    EntityAttrName="CountryTypeCode"
    EntityUsage="Customers"
    AliasName="COUNTRY_TYPE_CODE"
    DefaultValue="INTERNATIONAL">
    <DesignTime>
      <Attr Name="_OverrideAttr" Value="true"/>
    </DesignTime>
  </ViewAttribute>
  <ViewAttribute
    Name="Language"
    PrecisionRule="true"
    EntityAttrName="Language"
    EntityUsage="Customers"
    AliasName="LANGUAGE"/>
</ViewObject>

サブタイプ・ビュー・オブジェクト定義の<AttrArray>タグが、各サブタイプで許可されたエンティティ・オブジェクトを識別している点に注意してください。したがって、各サブタイプ・ビュー・オブジェクトは、単一のサブタイプ・エンティティ・オブジェクトを指定するはずです。サブタイプ・ビュー・オブジェクト定義の<AttrArray>タグが複数のエンティティ・オブジェクトを指定している場合、未使用のものを削除できます。この状況は、図7-6に示すように、ビュー・オブジェクトの作成ウィザードを使用してサブタイプ・ビュー・オブジェクトを作成したが、「サブタイプの選択」ダイアログでデフォルト・サブタイプ・エンティティ・オブジェクトのリストを縮小しなかった場合に発生します。デフォルトで、このダイアログではすべてのサブタイプ・エンティティ・オブジェクトが選択されます。

多相エンティティ・オブジェクトの慣用名に関する必知事項

多相エンティティ・オブジェクトの慣用名からビュー・オブジェクトを派生させる場合は、識別子属性による問合せのフィルタリングによって期待するサブタイプのみが含まれるように、次のベスト・プラクティスに従うことをお薦めします。

問合せでは期待するエンティティ・サブタイプに行を制限する必要がある

ビュー・オブジェクトが階層で使用可能なエンティティ・サブタイプのサブセットのみを使用する場合は、識別子列が期待するエンティティ・タイプと一致する行のみを返すように問合せを制限する適切なWHERE句を含める必要があります。問合せでサブタイプのフィルタリングを行うときには、識別子属性のみに依存しないでください。問合せを絞り込むための属性を追加しないと、ビュー・オブジェクトでは事実上すべての行に問合せが実行され、どの識別子の値にも一致しない列がクライアントで破棄されることになります。

委譲を使用したビュー行での選択したエンティティ・メソッドの公開

設計上、クライアントはエンティティ・オブジェクトを直接使用しません。かわりに、当面のタスクに関連する情報のセットを表す適切なビュー・オブジェクトのビュー行を通して、間接的にエンティティ・オブジェクトを使用します。ビュー・オブジェクトは、当面のタスクに関連する1つまたは複数のエンティティ・オブジェクトの基礎となる属性の特定のセットを公開できるのと同じように、これらのエンティティから選択されたメソッドのセットも公開できます。そのためには、カスタム・ビュー行のJavaクラスを有効にし、次のビュー行クラスでメソッドを記述します。

  • ビュー行で生成されるエンティティ・アクセッサを使用して基礎となる適切なエンティティ行にアクセス

  • そのメソッドの呼出し

たとえば、Customersエンティティ・オブジェクトに、そのCustomersImplクラスのperformCustomerFeature()メソッドが含まれているとします。このメソッドをCustomerListビュー行でクライアントに公開するには、カスタム・ビュー行のJavaクラスを有効にし、次の例に示すようにメソッドを記述します。

// In CustomerListRowImpl.java
public void performCustomerFeature() {
  getTheCustomer().performCustomerFeature();
}

JDeveloperは、エンティティ・オブジェクトの慣用名の別名に基づいて、関係する各エンティティ・オブジェクトの慣用名に対するビュー行クラスで、エンティティ・アクセッサ・メソッドを生成します。CustomerListビュー・オブジェクトでのCustomersエンティティの別名はTheCustomerであるため、そのエンティティ・オブジェクトの慣用名に関係するエンティティ行部分を返すためのgetTheCustomer()メソッドを生成します。

ビュー行のperformCustomerFeature()メソッドのコードでは、このgetTheCustomer()メソッドを使用して基礎となるCustomersImplエンティティ行クラスにアクセスし、そのperformCustomerFeature()メソッドを呼び出します。このコーディング・スタイルは委譲と呼ばれるもので、ビュー行メソッドはそのメソッドの1つの実装を、基礎となるエンティティ・オブジェクトの対応するメソッドに委譲します。多相エンティティ・オブジェクトの慣用名のあるビュー行で委譲が使用されると、委譲されたメソッド呼出しは、基礎となる適切なエンティティ行サブタイプによって処理されます。つまり、CustomersImplクラス、DomesticsImplクラスおよびInternationalsImplクラスが異なる方法でperformCustomerFeature()メソッドを実装している場合は、現在行のエンティティ・サブタイプに応じて、適切な実装が使用されます。

クライアント行インタフェースでこのメソッドを公開すると、クライアント・プログラムは、カスタム行インタフェースを使用して、特定のビュー行でカスタム・ビジネス機能を呼び出すことができます。次の例は、TestEntityPolymorphismクラスのコード行を示しています。CustomerListビュー・オブジェクト・インスタンスのすべての行を反復し、各行をカスタムのCustomerListRowインタフェースにキャストして、performCustomerFeature()メソッドを呼び出しています。

CustomerList customerlist = (CustomerList)am.findViewObject("CustomerList");
customerlist.executeQuery();
while (customerlist.hasNext()) {
  CustomerListRow customer = (CustomerListRow)customerlist.next();
  System.out.print(customer.getEmail()+"->");
  customer.performCustomerFeature();
}

前述の例のクライアント・コードを実行すると、次のような出力が生成されます。

austin->## performCustomerFeature as Domestics
hbaer->## performCustomerFeature as Internationals
:
sking->## performCustomerFeature as Domestic
:

Customersエンティティに関連する行では、CustomersImplクラスのperformCustomerFeature()メソッドが使用されたことを確認するメッセージが表示されます。Domesticsエンティティに関連する行とInternationalsエンティティに関連する行では異なるメッセージが表示され、DomesticsImplクラスとInternationalsImplクラスが継承されたperformCustomerFeature()メソッドに関して持っている異なる実装がはっきり示されます。

目的のエンティティ・サブタイプでの新しい行の作成

多相エンティティ・オブジェクトの慣用名のあるビュー・オブジェクトでは、新しいビュー行を作成すると、それにはベース・エンティティ・オブジェクトの慣用名と一致する型を持つ新しいエンティティ行部分が含まれます。かわりにいずれかのエンティティ・サブタイプで新しいビュー行を作成するには、createAndInitRow()メソッドを使用します。

次の例は、CustomerListビュー・オブジェクトのJavaクラスにおける2つのカスタム・メソッドを示しており、これらのメソッドでは、createAndInitRow()を使用して、クライアントがDomesticsまたはInternationalsサブタイプのエンティティ行を持つ新しい行を作成できるようにしています。createAndInitRow()を使用するには、例で示されているように、NameValuePairsオブジェクトのインスタンスを作成し、それに識別子属性の適切な値を設定します。次に、そのNameValuePairscreateAndInitRow()メソッドに渡し、指定した識別子属性の値に基づいて、適切なエンティティ行サブタイプを持つ新しいビュー行を作成します。

// In CustomerListImpl.java
public CustomerListRow createCustomersRow() {
  NameValuePairs nvp = new NameValuePairs();
  nvp.setAttribute("CustomerTypeCode","DOMESTIC");
  return (CustomerListRow)createAndInitRow(nvp);
}
public CustomerListRow createInternationalsRow() {
  NameValuePairs nvp = new NameValuePairs();
  nvp.setAttribute("CustomerTypeCode","INTERNATIONAL");
  return (CusotmersListRow)createAndInitRow(nvp);
} 

このようなメソッドをビュー・オブジェクトのカスタム・インタフェースで公開すると、実行時に、クライアントはそれを呼び出して、適切なエンティティ・サブタイプを持つ新しいビュー行を作成できます。次の例は、TestEntityPolymorphismクラスのこの機能に関連する行を示しています。最初に、createRow()メソッド、createDomesticsRow()メソッドおよびcreateInternationalsRow()メソッドを使用して、3つの新しいビュー行を作成します。次に、新しい行のそれぞれで、CustomerListRowカスタム・インタフェースからperformCustomerFeature()メソッドを呼び出します。

// In TestEntityPolymorphism.java
CustomerListRow newCustomer = (CustomerListRow)CustomerList.createRow();
CustomerListRow newDomestic  = Customerlist.createDomesticsRow();
CustomerListRow newInternational = Customerlist.createInternationalsRow();
newCustomer.performCustomerFeature();
newDomestic.performCustomerFeature();
newInternational.performCustomerFeature();

各行は期待したとおりに関連するエンティティ行のサブタイプに固有の方法でメソッドを処理し、結果を生成します。

## performCustomerFeature as Customer
## performCustomerFeature as Domestic
## performCustomerFeature as International

多相ビュー行関連の作業

ADFビジネス・コンポーネントを使用すると、多相ビュー行を保持するようにビュー・オブジェクトを構成できます。このため、クライアントでは特定のビュー行インタフェースを使用して様々なビュー行の型にアクセスできます。

「多相エンティティ・オブジェクトの慣用名での作業」で示されている例では、「舞台裏」であるエンティティ・オブジェクト・レベルでポリモフィズムが発生していました。クライアント・コードは同じCustomerListRowインタフェースを使用してすべてのビュー行を処理するので、Domesticsエンティティ・オブジェクトに基づく行と、Customersエンティティ・オブジェクトに基づく行を区別することはできません。コードは、基礎となるエンティティ・サブタイプのすべての型に共通するビュー行属性とメソッドの同じセットを使用して、すべてのビュー行を処理します。

多相ビュー行をサポートするようにビュー・オブジェクトを構成すると、クライアントは、行の型に固有のビュー行インタフェースを使用して、異なる型のビュー行を処理できます。このようにすると、クライアントは、必要に応じて、特定のサブタイプに固有のビュー属性にアクセスしたり、ビュー行メソッドを呼び出したりできます。図7-11は、前述のCustomerListの例に対してこの機能を有効にするビュー・オブジェクトの階層を示しています。DomesticListInternationalListは、ベース(または親)のCustomerListビュー・オブジェクトを拡張した子ビュー・オブジェクトです。それぞれが、エンティティ・オブジェクトの慣用名として保持する、Customersのそのサブタイプに固有の追加属性を含んでいることに注意してください。DomesticListにはState追加属性が含まれ、InternationalListにはState属性はないものの、Language属性が含まれています。ビュー行ポリモフィズム用に構成されている場合、クライアントは次のものを使用してCustomerListビュー・オブジェクトの結果を処理できます。

  • 顧客に関係するビュー行のCustomerListRowインタフェース

  • 国内顧客に関係するビュー行のDomesticListRowインタフェース

  • 国際顧客に関係するビュー行のInternationalListRowインタフェース

これにより、クライアントは、特定のサブタイプのビュー行に固有の追加属性とビュー行メソッドにアクセスできます。

図7-11 ビュー行ポリモーフィズムを有効にするビュー・オブジェクト・サブタイプの階層

この図は周囲のテキストで説明しています

ノート:

この項の例では、SummitADF_Examplesアプリケーション・ワークスペースのoracle.summit.model.polymorphicvoパッケージを参照します。

多相ビュー行を持つビュー・オブジェクトの作成方法

多相ビュー行によって作成するビュー・オブジェクトは、それぞれに固有のベース・エンティティ・オブジェクトを持つビュー・オブジェクトの階層から、1つ以上の属性を継承できます。拡張されたビュー・オブジェクトから選択する属性は、親ビュー・オブジェクトの多相ビュー行定義によってオーバーライドされます。

多相ビュー行を持つビュー・オブジェクトを作成するには:

  1. Application Navigatorで、継承階層にある、ベース・ビュー・オブジェクトにするビュー・オブジェクトをダブルクリックします。

    たとえば、CustomerListビュー・オブジェクトは、DomesticListビュー・オブジェクトのベースです。

  2. ビュー・オブジェクトの概要エディタで「属性」ナビゲーション・タブをクリックし、ビュー行の、使用するビュー行インタフェースを区別する識別子属性を選択して、「選択した属性の編集」ボタンをクリックします。

    たとえば、CustomerTypeCodeは、CustomerListの識別子属性です。

  3. 「属性の編集」ダイアログで、Discriminatorチェック・ボックスを選択して、「デフォルト値」を入力し、「OK」をクリックします。

    ベース・ビュー・オブジェクトのビュー行インタフェースが使用するものと予想される属性値に一致する値を、「デフォルト値」フィールドで指定する必要があります。たとえば、CustomerListビュー・オブジェクトでは、CustomerTypeCode属性を識別子属性としてマークし、デフォルト値をCUSTOMERにします。

  4. ビュー・オブジェクトの概要エディタの「属性」ページで、サブタイプ・ビュー・オブジェクトに固有のすべての属性を削除します。

    たとえば、属性Statesは、DomesticListサブタイプ・ビュー・オブジェクトのみによって使用されるため、ベース・ビュー・オブジェクトから削除されます。

  5. 概要エディタで「Java」ナビゲーション・タブをクリックして、ベース・ビュー・オブジェクトのカスタム・ビュー行クラスを有効にし、少なくとも1つのメソッドをクライアント行インタフェースで公開します。このメソッドとしては、ビュー行属性アクセッサ・メソッドの1つまたは全部、および任意のカスタム・ビュー行メソッドを使用できます。

  6. ベース・ビュー・オブジェクトを拡張する新しいサブタイプ・ビュー・オブジェクトを作成します。

    1. Application Navigatorでベース・ビュー・オブジェクトを右クリックして新規拡張オブジェクトを選択し、拡張オブジェクトの作成ダイアログで、サブタイプ・ビュー・オブジェクトを指名します。

      この例では、CustomerListビュー・オブジェクトがベースで、サブタイプ・ビュー・オブジェクトは指定されたDomesticListです。

    2. サブタイプ・ビュー・オブジェクトの概要エディタで「属性」ナビゲーション・タブをクリックして、「追加」ボタンのドロップダウンから「エンティティからの属性の追加」を選択し、「属性」ダイアログで、サブタイプ・ビュー・オブジェクトに固有の属性を追加して、「OK」をクリックします。

      この例では、サブタイプDomesticListが追加の属性Stateを定義します。

    3. 概要エディタの「属性」ページでビュー行の識別子属性を選択し、「オーバーライド」をクリックして、「選択した属性の編集」ボタンをクリックします。

    4. 「属性の編集」ダイアログで、識別子属性に別個のデフォルト値を指定して拡張ビュー・オブジェクトのサブタイプを定義し、「OK」をクリックします。

      たとえば、DomesticListビュー・オブジェクトは、CustomerTypeCode識別子属性にDOMESTICという値を設定しています。

    5. 概要エディタで「Java」ナビゲーション・タブをクリックして、拡張ビュー・オブジェクトのカスタム・ビュー行クラスを有効にします。

      妥当な場合は、新しいカスタム・ビュー行メソッドを追加するか、または親ビュー・オブジェクトの行クラスから継承するカスタム・ビュー行メソッドをオーバーライドします。

    6. 必要に応じて繰り返し、他の拡張されたビュー・オブジェクトを追加します。

      たとえば、InternationalListは、CustomerListを拡張する2番目のビュー・オブジェクトです。このオブジェクトでは、CustomerTypeCode識別子属性に値INTERNATIONALを設定しています。

ビュー・オブジェクトの階層を設定した後、「サブタイプ・オブジェクトの慣用名を表示するためのアプリケーション・モジュールの更新」の説明に従い、ビュー行ポリモフィズムに参加するビュー・オブジェクト・サブタイプのリストを定義する必要があります。たとえば、ビュー・インスタンスCustomerList1を持つCustomersModuleアプリケーション・モジュールは、DomesticListおよびInternationalListの各サブタイプ・ビュー・オブジェクトを指定するように構成する必要があります。

多相ビュー行を持つビュー・オブジェクトを作成する場合の処理

多相ビュー行定義を持つ子ビュー・オブジェクトを定義するために使用するベース・ビュー・オブジェクトを作成する場合、JDeveloperはベース・ビュー・オブジェクトのXMLドキュメントに、識別子属性に関する情報を追加します。たとえば、CustomerListビュー・オブジェクトを作成すると、XMLプロパティDiscrColumnは、CountryTypeCodeを、ベース・ビュー・オブジェクトの多相識別子属性として識別し、次のようにサブタイプ値をCUSTOMERとします。

<ViewObject
  Name="CustomerList" ... >
  <EntityUsage
    Name="Customers"
    Entity="oracle.summit.model.polymorphics.entities.Customers" >
  </EntityUsage>
...
  <ViewAttribute
    Name="CountryTypeCode"
    PrecisionRule="true"
    EntityAttrName="CountryTypeCode"
    EntityUsage="Customers"
    AliasName="COUNTRY_TYPE_CODE"
    DiscrColumn="true"
    DefaultValue="CUSTOMER">
  </ViewAttribute>
   ...
</ViewObject>

続いて、多相ビュー行定義を持つ子ビュー・オブジェクトを作成する場合、JDeveloperは、子ビュー・オブジェクトのXMLドキュメントに、ビュー行定義に関する情報を追加します。たとえば、次の例は、ベース・ビュー・オブジェクトの名前がExtendsプロパティ内に記録されたDomesticList子ビュー・オブジェクトを示しています。XMLプロパティDiscrColumnは、オーバーライドされたCountryTypeCode属性を、DOMESTICのサブタイプ値を持つ多相識別子属性として識別します。サブタイプに固有の追加の属性Stateのみが、子ビュー・オブジェクトのXMLドキュメントに表示されます。

<ViewObject
  Name="DomesticList"
  Extends="oracle.summit.model.polymorphic.views.CustomerList"
  ...>
  <ViewAttribute
    Name="CountryTypeCode"
    PrecisionRule="true"
    DiscrColumn="true"
    EntityAttrName="CountryTypeCode"
    EntityUsage="Customers"
    AliasName="COUNTRY_TYPE_CODE"
    DefaultValue="DOMESTIC">
    <DesignTime>
      <Attr Name="_OverrideAttr" Value="true"/>
    </DesignTime>
  </ViewAttribute>
  <ViewAttribute
    Name="State"
    PrecisionRule="true"
    EntityAttrName="State"
    EntityUsage="Customers"
    AliasName="STATE"/>
</ViewObject>

同様に、次に示すように、InternationalList子ビュー・オブジェクトのXMLドキュメントでは、同じベース・ビュー・オブジェクトの名前がそのXMLドキュメントのExtendsプロパティ内に指定されていますが、INTERNATIONALというサブタイプ値を持つ多相識別子属性と、そのサブタイプに固有の追加属性Languageが定義されています。

<ViewObject
  Name="InternationalList"
  Extends="oracle.summit.model.polymorphic.views.CustomerList"
  ... >
  <ViewAttribute
    Name="CountryTypeCode"
    PrecisionRule="true"
    DiscrColumn="true"
    EntityAttrName="CountryTypeCode"
    EntityUsage="Customers"
    AliasName="COUNTRY_TYPE_CODE"
    DefaultValue="INTERNATIONAL">
    <DesignTime>
      <Attr Name="_OverrideAttr" Value="true"/>
    </DesignTime>
  </ViewAttribute>
  <ViewAttribute
    Name="Language"
    PrecisionRule="true"
    EntityAttrName="Language"
    EntityUsage="Customers"
    AliasName="LANGUAGE"/>
</ViewObject>

「多相エンティティ慣用名によりサブタイプ・ビュー・オブジェクトを作成すると行われる処理」で説明した多相エンティティ慣用名の例とは異なり、多相ビュー行を持つビュー・インスタンスは継承およびオーバーライド属性を使用して、たとえば、Domesticsエンティティ・オブジェクトをベースとする行と、Customersエンティティ・オブジェクトをベースとする行とを区別します。このように、許可されたサブタイプ・エンティティ・オブジェクトの定義は、多相ビュー行の場合、ビュー・オブジェクトのXMLドキュメントには存在しません(多相エンティティ・オブジェクトの慣用名の場合は、<AttrArray>タグで定義されます)。

多相ビュー行に関する必知事項

多相ビュー行を操作する場合は、行の型を扱って、表示する属性をカスタマイズするか、ビュー行のエンティティ・サブタイプに固有のメソッドに委譲を行うことができます。

拡張されたビュー・オブジェクトでのサブタイプ固有の属性の選択

拡張されたビュー・オブジェクトを作成すると、そのオブジェクトは親のエンティティ・オブジェクトの慣用名を継承します。親のビュー・オブジェクトのエンティティ・オブジェクトの慣用名がドメイン・レイヤーのサブタイプを持つエンティティ・オブジェクトに基づいている場合は、継承した親のエンティティ・オブジェクトの慣用名型ではなく、これらのサブタイプのいずれかを拡張されたビュー・オブジェクトが使用するようにする場合があります。このようにするには2つの理由があります。

  • エンティティ・サブタイプに固有の属性を選択するため

  • エンティティ・サブタイプに固有のメソッドに委譲するビュー行メソッドを作成できるようにするため

これを行うには、継承されたエンティティ・オブジェクトの慣用名をオーバーライドして、目的のエンティティ・サブタイプを参照する必要があります。そのためには、拡張されたビュー・オブジェクトの概要エディタで次のステップを行います。

ビュー・オブジェクトのエンティティ・オブジェクト慣用名をオーバーライドするには:

  1. 「アプリケーション」ウィンドウで、オーバーライドするエンティティ・オブジェクトの慣用名を含むビュー・オブジェクトをダブルクリックします。
  2. 概要エディタで「エンティティ・オブジェクト」ナビゲーション・タブをクリックして、拡張されたエンティティ・オブジェクトの慣用名を使用していることを確認します。

    たとえば、DomesticListビュー・オブジェクトを拡張するDomesticListビュー・オブジェクトを作成するときは、最初、「選択済」リストに、TheCustomerという別名を使用するエンティティ・オブジェクトの慣用名が「TheCustomer(Customers): 拡張済」のように表示されます。エンティティ・オブジェクトの慣用名の型はカッコ内で示され、「拡張済」というラベルはエンティティ・オブジェクトの慣用名が現在は親から継承されていることを示します。

  3. 「使用可能」リストで、継承されたものをオーバーライドする目的のエンティティ・サブタイプを選択します。既存のエンティティ・オブジェクトの慣用名型のサブタイプ・エンティティである必要があります。

    たとえば、Customersエンティティ型に基づいて継承されたエンティティ・オブジェクトの慣用名をオーバーライドするには、「使用可能」リストでDomesticsエンティティ・オブジェクトを選択します。

  4. 「>」をクリックして、「選択済」リストに移動します。
  5. 表示される警告に応答し、既存の継承されたエンティティ・オブジェクトの慣用名をオーバーライドすることを確認します。

このステップを実行すると、「選択済」リストが更新されて、オーバーライドされたエンティティ・オブジェクトの慣用名を反映するようになります。たとえば、DomesticListビュー・オブジェクトの場合は、Customersベースのエンティティ・オブジェクトの慣用名をDomesticsエンティティ・サブタイプでオーバーライドすると、表示が「TheCustomer (Domestics): オーバーライド済」に更新されます。

エンティティ・オブジェクトの慣用名をエンティティ・サブタイプに関係するようにオーバーライドした後は、エディタの「属性」タブを使用して、そのサブタイプに固有の追加属性を選択できます。たとえば、DomesticsListビュー・オブジェクトには、Domesticsエンティティ・オブジェクトに固有の、Stateという名前の追加属性が含まれます。

エンティティ・オブジェクトの慣用名をオーバーライドした後のサブタイプ固有のメソッドへの委譲

拡張されたビュー・オブジェクトのエンティティ・オブジェクトの慣用名をサブタイプ・エンティティを参照するようにオーバーライドした後は、サブタイプ・エンティティ・クラスに固有のメソッドに委譲するビュー行メソッドを作成できます。

次の例は、InternationalListビュー・オブジェクトに対するカスタム・ビュー行クラスのperformInternationalFeature()メソッドのコードを示しています。getTheCustomer()エンティティ行アクセッサからの戻り値をサブタイプInternationalsImplにキャストした後、Internationalsエンティティ・オブジェクトに固有のperformInternationalFeature()メソッドをコールしています。

// In InternationalListRowImpl.java
public void performInternationalFeature() {
   InternationalsImpl international = (InternationalsImpl)getTheCustomer();
   international.performInternationalFeature();
}

ノート:

JDeveloperでは、InternationalListRowImplのようなサブクラスがgetTheCustomer()のようなメソッドをオーバーライドしてその戻り型を変更できるようにする共変戻り型と呼ばれるJDKの機能がまだ採用されていないため、ここではエンティティ・サブタイプに明示的にキャストする必要があります。

クライアント・コードでの異なるビュー行インタフェース型の使用

次の例、次のステップを実行するTestViewRowPolymorphismクラスのコード行を示しています。

  1. CustomerListビュー・オブジェクトの行を反復処理します。

    ループでは、各行について、Javaのinstanceof演算子を使用して、現在の行がDomesticListRowまたはInternationalListRowのインスタンスかどうかを検査しています。

  2. 行がDomesticListRowの場合は、行をこのさらに具体的な型にキャストした後、次の処理を行います。

    • DomesticListRowインタフェースに固有のperformDomesticFeature()メソッドをコールします。

    • DomesticListビュー・オブジェクトに固有のState属性の値にアクセスします。

  3. 行がInternationalListRowの場合は、行をこのさらに具体的な型にキャストした後、次の処理を行います。

    • InternationalListRowインタフェースに固有のperformInternationalFeature()メソッドをコールします。

    • InternationalListビュー・オブジェクトに固有のLanguage属性の値にアクセスします。

  4. それ以外の場合は、CustomerListRowでメソッドをコールします。

// In TestViewRowPolymorphism.java
ViewObject vo = am.findViewObject("CustomerList");
vo.executeQuery();
// 1. Iterate over the rows in the CustomerList view object
while (vo.hasNext()) {
  CustomerListRow Customer = (CustomerListRow)vo.next();
  System.out.print(Customer.getEmail()+"->");
  if (Customer instanceof DomesticListRow) {
    // 2. If the row is a DomesticListRow, cast it
    DomesticListRow mgr = (DomesticListRow)Customer;
    mgr.performDomesticFeature();       
    System.out.println("State: "+domestic.getState());
  }
  else if (Customer instanceof InternationalListRow) {
    // 3. If the row is an InternationalListRow, cast it
    InternationalListRow international = (InternationalListRow)Customer;
    international.performInternationalFeature();       
    System.out.println("Speaks English: "+international.getLanguage());        
  }
  else {
    // 4. Otherwise, just call a method on the CustomerListRow 
    Customer.performCustomerFeature();
  }
}

前述の例のコードを実行すると、次のような出力が生成されます。

daustin->## performInternationalFeature called
English spoken: Yes
hbaer->## performCustomerFeature as Customer
:
sking->## performDomesticFeature called
State: CA
:

これは、ビュー行ポリモーフィズムの機能を使用することで、クライアントが異なる型のビュー行を区別し、ビュー行の各サブタイプに固有のメソッドと属性にアクセスできたことを示します。

識別子属性に関する必知事項

ADFビュー・オブジェクトでエンティティ・オブジェクトの参照に使用する識別子属性を問合せに含めるか除外するかを選択できます。

ビュー・オブジェクトが、識別子属性を持つエンティティ・オブジェクトを参照する場合に、その識別子属性を(主キー属性に加えて)問合せに含めるには、ビュー・オブジェクトの概要エディタの「属性」ページの「詳細」タブで、継承した識別子属性に対応する「多相識別子」チェック・ボックスを選択します。

チェック・ボックスを有効化する場合、「詳細」タブの「多相識別子」オプションを使用して、ビュー・オブジェクトがサブタイプ・ビュー・オブジェクトとして定義されるかどうかを構成できます。

  • オプション「View」を有効化すると、多相ビュー行は有効化されます。

  • オプション「エンティティ」を有効化すると、ビュー行の識別子機能が無視され、そのかわりに属性がデフォルト値でインスタンス化されます。

    「エンティティ」オプションは、識別子属性が、複数のバッキング・エンティティ・オブジェクトを持つエンティティ・ベースのビュー・オブジェクトによって継承されているが、多相ビュー行では都合が悪い状況で役立ちます。

図7-12は、DomesticListビュー・オブジェクトの「詳細」タブで、その、Customersエンティティ・オブジェクトから継承したCustomerTypeCode識別子属性が有効化されていることを示しています。「View」を選択するとは、この識別子属性がビュー・オブジェクト・ポリモフィズムに参加し、値DOMESTICがサブタイプ・ビュー・オブジェクトの行タイプを決定することを意味します。

図7-12 識別子属性選択によるビュー行ポリモフィズムの有効化

図7-12の説明が続きます
「図7-12 識別子属性選択によるビュー行ポリモフィズムの有効化」の説明

サブタイプ・オブジェクトの慣用名を表示するためのアプリケーション・モジュールの更新

ベース・ビュー・オブジェクト・インスタンスのビュー・オブジェクト・サブタイプのリストをADFアプリケーション・モジュール定義で指定できます。

ビュー行ポリモフィズムまたはエンティティ・オブジェクト・ポリモフィズムを使用してビュー・オブジェクト階層を作成した後で、実行時にビュー・オブジェクト・ポリモフィズムに参加するビュー・オブジェクト・サブタイプのリストを定義する必要があります。これを達成するには、ベース・ビュー・インスタンスのサブタイプ・ビュー・オブジェクトを指定してアプリケーション・モジュール定義を更新します。実行時に、ADFは、起動されたビュー・インスタンスの名前付きサブタイプの定義に基づいて多相ビュー行を作成します。

データ・モデル上でのサブタイプ・オブジェクトの慣用名の公開方法

ビュー行ポリモフィズムまたはエンティティ・オブジェクト・ポリモフィズムを使用してビュー・オブジェクト階層を作成した後で、ビュー・オブジェクト・ポリモフィズムに参加するビュー・オブジェクト・サブタイプのリストを定義する必要があります。これを達成するには、ベース・ビュー・インスタンスのサブタイプ・ビュー・オブジェクトを指定してアプリケーション・モジュール定義を更新します。

図7-13に示すように、ベース・ビュー・オブジェクトの慣用名CustomerList1を公開するデータ・モデルは変わりませんが、「サブタイプの選択」ダイアログを使用して、ベース・ビュー・オブジェクトの、可能性のある多相ビュー・オブジェクトの慣用名が定義されます。

Figure 7-13 サブタイプ・ビュー・オブジェクトによるアプリケーション・モジュール定義の更新

この図は周囲のテキストで説明しています

始める前に:

多相ビュー・オブジェクトに関する知識が役立つ場合があります。詳細は、「多相ビュー行関連の作業」を参照してください。

ビュー・オブジェクトがエンティティ・サブタイプの継承から導出する多相エンティティ・オブジェクトの慣用名に基づいてサブタイプ・ビュー・オブジェクトを作成する場合は、ベースのエンティティ・ベース・ビュー・オブジェクトを拡張するサブタイプ・ビュー・オブジェクトを作成します。詳細は、「多相エンティティ・オブジェクトの慣用名での作業」を参照してください。

定義するビュー・オブジェクト階層から導出された多相ビュー行に基づいてサブタイプ・ビュー・オブジェクトを作成する場合は、多相識別子属性を持つサブタイプ・ビュー・オブジェクトを作成します。詳細は、「多相ビュー行関連の作業」を参照してください。

アプリケーション・モジュール定義にサブタイプ・ビュー・オブジェクトを追加するには:

  1. アプリケーション・モジュールの概要エディタで「データ・モデル」ナビゲーション・タブをクリックし、アプリケーション・モジュールのデータ・モデルに、ベース・ビュー・オブジェクトのインスタンスを追加します。

    たとえば、CustomerListビュー・オブジェクトが2つのサブタイプ、DomesticListおよびInternationalListビュー・オブジェクトをサポートする場合、AppModuleアプリケーション・モジュールは、ベース・ビュー・インスタンスCustomerList1を持ちます。

  2. 「データ・モデル」ページで、「ビュー・オブジェクト・インスタンス」セクションを展開し、「データ・モデル」リストで、「サブタイプ」ボタンをクリックします。

    ボタンをクリックするために、「データ・モデル」リストでビュー・インスタンスを選択する必要はありません。

  3. 「サブタイプ」ダイアログで、目的に応じてベース・ビュー・インスタンスのビュー・オブジェクト・サブタイプを「使用可能」から「選択済」リストに移動し(またはその逆)、「OK」をクリックします。

    たとえば、サブタイプ・ビュー・オブジェクトDomesticListおよびInternationalListを持つCustomerList1ビュー・インスタンスの場合、図7-13に示すように、両方のビュー・オブジェクトを「選択済」リストに移動します。

サブタイプ・ビュー・オブジェクトをアプリケーション・モジュールに追加した場合に行われる処理

アプリケーション・モジュールにサブタイプ・ビュー・オブジェクトを追加すると、JDeveloperは、許可されているビュー・サブタイプに関する情報をアプリケーション・モジュールのXMLドキュメントに追加します。たとえば、2つの可能なサブタイプ・オブジェクトの慣用名を持つビュー・インスタンスCustomerList1を定義する場合、許可されているサブタイプ・ビュー・オブジェクトの名前が、次のように<AttrArray>タグに記録されます。

<AppModule
  ...
  <ViewUsage
    Name="CustomerList1"
    ViewObjectName="oracle.summit.model.polymorphicsample.CustomerList"/>
  <AttrArray Name="ViewImports">
    <Item Value="oracle.summit.model.polymorphicsample.DomesticList"/>
    <Item Value="oracle.summit.model.polymorphicsample.InternationalList"/>
  </AttrArray>
</AppModule>