ヘッダーをスキップ
Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド
11gリリース1 (11.1.1.7.0)
B52028-05
  目次へ移動
目次

前
 
次
 

7 検証とビジネス・ルールの宣言的な定義

この章では、Oracle Application Development Framework (Oracle ADF)アプリケーションに宣言的検証を実装する一般的なビジネス・ルールを作成するためにADFエンティティ・オブジェクトを使用する方法について説明します。

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

7.1 宣言的検証の概要

検証ルールを作成および管理する最も容易な方法は、宣言的検証ルールを使用することです。宣言的検証規則は概要エディタを使用して定義され、いったん作成されると、エンティティ・オブジェクトのXMLファイルに保存されます。宣言的検証は、エンティティ・オブジェクトのJavaファイルに保存されているプログラムによる検証(第8章「プログラムによる検証とビジネス・ルールの実装」)とは異なります。

Oracle ADFでは、大部分のビジネス上のニーズを満たすことができる組込みの宣言的な検証ルールが用意されています。再利用するカスタム検証規則がある場合は、コーディングを行ってIDEに追加し、JDeveloperから直接規則を利用できます。カスタム検証規則は高度なトピックで、38.9項「カスタム検証規則の実装」で説明しています。 7.5項「検証とビジネス・ルールでのGroovy式の使用」で使用されているように、Groovy式を検証の基礎にすることもできます。

検証ルールを追加する際、適切なエラー・メッセージを提供し、後に必要に応じて容易に他の言語に翻訳できます。検証のトリガー方法を定義し、重大度レベルを設定することもできます。

宣言的検証を使用する利点の1つ(独自の検証を記述することに対して)は、検証のフレームワークによりバッチ検証例外の複雑性が自動的に処理されることです。これにより、自由にアプリケーションの固有の検証規則ロジックに専念できます。


注意:

必要に応じて、宣言的動作を超えて、より複雑な検証規則をビジネス・ドメイン・レイヤーに実装することができます。Method Validatorを使用したカスタム検証コードの起動方法は8.2項「Method Validatorの使用」、独自のカスタム規則を使用した宣言的規則の基本セットの拡張方法の詳細は38.9項「カスタム検証規則の実装」を参照してください。


7.1.1 ビジネス・レイヤー検証またはモデル・レイヤー検証を使用する場合

ADFビジネス・コンポーネント・アプリケーションでは、検証コードの大半がエンティティ・オブジェクト内で定義されます。ビジネス・ロジックをこのように再利用可能な共有コンポーネントにカプセル化することにより、ビジネス情報にアクセスするすべてのビュー・オブジェクトやクライアントで情報が一貫して検証され、検証の保管先を集中化することによって管理が容易になります。

モデル・レイヤーでは、ADFモデル検証規則をコレクションの属性に設定できます。エンティティ・オブジェクトで利用できる宣言的検証機能の多くはモデル・レイヤーでも利用でき、アプリケーションはビジネス・レイヤー検証に加えてモデル・レイヤー検証の使用も保証する必要があります。

ADFビジネス・コンポーネント・アプリケーション・モジュールのデータ・コントロールを使用する場合、モデル・レイヤー検証を使用する必要はありません。可能であれば、すべての検証規則を、ビジネス・レイヤー内の再使用と管理が容易で一元管理されたエンティティ・オブジェクトに定義することを検討してください。その他のデータ・コントロール・タイプでは、モデル・レイヤー検証のほうが便利です。

7.2 検証サイクルの理解

それぞれのエンティティ行は、データが有効であるかどうかを追跡します。既存のエンティティ行をデータベースから取得すると、エンティティは有効であると判断されます。既存のエンティティ行の最初の持続属性が変更された場合、または、新しいエンティティ行が作成された場合、エンティティは無効であるとマークされます。

エンティティが無効な状態にある場合、エンティティを有効にする前に、構成した宣言的な検証と、実装したプログラム的な検証規則が再度評価されます。あるエンティティ行が実行時に有効であるかどうかは、その行でisValid()メソッドをコールして確認できます。


注意:

属性は(デフォルトで)空欄のままにできるため、属性に値が含まれていない場合、検証はトリガーされません。たとえば、ユーザーが新しいエンティティ行を作成して特定の属性の値を入力しなかった場合、その属性に関する検証は実行されません。この状況で検証を強制的に実行するには、属性に必須フラグを設定します。


7.2.1 エンティティ・オブジェクト検証規則のタイプ

エンティティ・オブジェクト検証規則は、属性レベルおよびエンティティレベルのいずれかの基本カテゴリに分類できます。

7.2.1.1 属性レベルの検証規則

特定のエンティティ・オブジェクト属性に対する属性レベルの検証規則は、エンド・ユーザーまたはプログラム・コードによる属性値の変更が試行されるとトリガーされます。属性を設定する順序は指定できないため、属性レベルの検証規則は、規則の成否がその属性の候補値のみに依存する場合にのみ使用する必要があります。

属性レベルの検証の例を次に示します。

  • 注文のOrderDateの値には、過去の日付は設定できません。

  • 製品のProductId属性は、既存の製品である必要があります。

7.2.1.2 エンティティレベルの検証規則

その他のすべての検証規則は、エンティティ・レベルの検証規則となります。これらの規則には、実装の際、規則の成否の決定に2つ以上のエンティティ属性、または、構成される子エンティティ行を考慮する必要があります。

エンティティ・レベルの検証の例を次に示します。

  • OrderShippedDateの値は、OrderDateより後の日付を設定します。

  • 注文のProductId属性は、既存の製品である必要があります。

エンティティ・レベルの検証規則は、Rowに対しvalidate()メソッドをコールするとトリガーされます。次の場合にトリガーされます。

  • エンティティ・オブジェクトにおいてメソッドを明示的にコールした場合

  • 無効なエンティティ行を含むビュー行においてメソッドを明示的にコールした場合

  • ビュー・オブジェクトのイテレータにより、現在の行の変更を許可する前に、ビュー・オブジェクトの現在の行に対してメソッドがコールされた場合

  • トランザクションのコミット時、データベースへ変更を送信する前に、保留中の変更リスト内の無効なエンティティが処理によって有効にされた場合

トランザクションのコミット処理の一環として、エンティティ・レベルの検証規則は複数回起動できます(指定された限度回数まで)。詳細は、7.2.4項「無限検証サイクルの回避」を参照してください。

7.2.2 コミット処理と検証の理解

トランザクションのコミット処理は、3つの基本的なフェーズに分かれています。

  1. 保留中の変更リスト内のすべての無効エンティティ行が有効であることを確認します。

  2. 適切なDML操作を実行し、保留中の変更をデータベースに送信します。

  3. トランザクションをコミットします。

エンティティ・オブジェクト内に、SELECT文内の送信済の変更の参照に応じて問合せまたはストアド・プロシージャを実行するようなビジネス検証ロジックがある場合、8.5.3項「ビュー・アクセッサでの行セット・アクセスに関する情報」に示すbeforeCommit()メソッドを使用してコーディングする必要があります。 このメソッドはすべてのDML文の適用後に起動され、そのメソッドから呼び出された問合せまたはストアド・プロシージャが、保存はされているがまだコミットされていない保留中のすべての変更を「見る」ことができるようにします。


注意:

同一のHTTPリクエスト内でトランザクションのコミットまたはロールバックが必ず実行される場合を除き、Webアプリケーションでトランザクション・レベルのpostChanges()メソッドを使用しないでください。このメソッドは、検証前の変更をコミットせず、トランザクションから強制的に送信します。使用した場合、複数の異なるクライアントにより、アプリケーション・モジュールとデータベース接続の両方がプールされ、シリアルに共有されるという事態が環境内で発生する可能性があります。


7.2.3 検証順序に対するコンポジットの影響

構成される側の子エンティティ行は、それを構成する親エンティティ・オブジェクトに不可欠であるとみなされるため、構成される側の子エンティティ行になんらかの変更を加えると、親エンティティは無効であるとマークされます。たとえば、注文の明細項目を変更する場合、注文全体が変更されるか無効であるとみなされます。

したがって、コンポジット・エンティティを検証する場合、現在無効な構成される側の子エンティティが最初に検証されます。この動作は再帰的で、無効な構成される側の子が存在する場合、さらに深くドリルします。

7.2.4 無限検証サイクルの回避

現在のエンティティや他のエンティティの属性を更新するコードが検証規則に含まれている場合、エンティティの検証により、対象のエンティティやその他のエンティティが無効になる場合があります。保留中の変更リスト内のすべての無効なエンティティを検証するトランザクションのコミット処理フェーズの一環として、このトランザクションは、保留中のすべてのエンティティ行が有効になるまで、1回につき保留中の変更リストを複数回(指定された限度回数まで)パスします。

検証のパスの最大回数は、トランザクション・レベルの検証しきい値設定によって指定します。この設定のデフォルト値は10です。後続のパスで自身を検証するための適切なロジックが関連のエンティティに含まれている場合は、しきい値の回数を複数回まで増やすことができます。

10回パスした後に、リスト内に無効なエンティティが残っている場合、次の例外が発生します。

JBO-28200: Validation threshold limit reached. Invalid Entities still in cache

これは、意図しないエンティティの無効化を繰り返すような処理を回避するため、検証規則コードをデバッグする必要があることを示しています。

しきい値を変更するには、例7-1に示すように、SetValidationThreshold()メソッドを使用します。この例では新しいしきい値が12です。

例7-1 検証しきい値の変更

oracle.jbo.server.DBTransaction::setValidationThreshold(12)

7.2.5 検証が失敗したときに行われる処理

エンティティ・オブジェクトの検証規則で例外がスローされた場合、その例外はバンドルされ、クライアントに戻されます。トランザクションのpostChanges処理中、イベントを処理するため上書きしたメソッドによって検証の失敗がスローされる場合、現在のpostChangesサイクルですでに実行されている可能性のあるデータベースのINSERTUPDATEおよびDELETE文がロールバックされます。


注意:

例外のバンドルは、ADFモデル・ベースのWebアプリケーションのデフォルトの動作ですが、ビジネス・コンポーネント・ブラウザまたはSwingのバインディングではデフォルトの動作ではありません。ビジネス・コンポーネント・ブラウザまたはSwingのクライアントでは、例外のバンドルに追加の構成が必要です。


7.2.6 エンティティ・オブジェクト行の状態の理解

エンティティ行がメモリー内にある場合、行の論理状態を反映したエンティティ状態になります。図7-1に、異なるエンティティ行の状態と、エンティティ行の状態の変化を示します。エンティティ行が最初に作成される場合、状態はNewです。setNewRowState()メソッドを使用すると、エンティティをInitializedとしてマーキングできます。これにより、エンティティはトランザクションの保留中の変更リストから除外され、ユーザーが1つ以上の属性を設定したときにNew状態に戻ります。これによって、複数の初期化行を作成し、ユーザーが修正したものだけをポストできます。

Unmodified状態とは、データベースから取得されてから、まだ変更されていないエンティティの状態を表します。また、NewまたはModified状態のエンティティがトランザクションのコミット完了後に遷移する状態でもあります。トランザクション内で削除のために保留中の場合は、Unmodifiedエンティティ行はDeleted状態へと遷移します。最終的に、New状態の行がトランザクションのコミット前に削除されたり、Unmodified状態の行が正常に削除された場合、その行はDead状態へと遷移します。

図7-1 エンティティ行の状態と遷移のダイアグラム

エンティティ行の状態と遷移の図

getEntityState()およびgetPostState()メソッドを使用すると、ビジネス・ロジック・コードのエンティティ行の現在の状態にアクセスできます。getEntityState()メソッドは、トランザクションに関するエンティティ行の現在の状態を返します。また、getPostState()メソッドは、postChanges()メソッドを使用してトランザクションをコミットせずに保留中の変更をポストした後の、データベースに関するエンティティ行の現在の状態を返します。

たとえば新しい行を開始すると、getEntityState()getPostState()の両方がSTATUS_NEWを返します。そして行をポストすると(コミットやロールバックの前)、その行のエンティティはSTATUS_NEWの状態になり、ポスト状態はSTATUS_UNMODIFIEDになります。その後その行を削除しても、トランザクションにとってその行はまだ新規のため、エンティティ状態はSTATUS_NEWのままになります。ただしポスト状態はSTATUS_DEADになります。

7.2.7 バンドル例外モードの理解

アプリケーション・モジュールにはバンドル例外モードと呼ばれる機能があり、Webアプリケーションは発生した最初のエラーのみでなく、失敗した検証例外の最大セットをエンド・ユーザーに簡単に提示できます。ADFビジネス・コンポーネント・アプリケーション・モジュール・プールでは、Webアプリケーションに対してバンドル例外モードをデフォルトで有効にしています。

このデフォルト設定は、通常変更する必要はありません。ただし、検証例外がスローされる方法に影響を与えることからデフォルトで有効になっていることを理解することが重要です。Java言語およびJavaランタイムは単一例外オブジェクトのスローのみをサポートするため、バンドルされた検証例外は、例外のセットを、それを含む新しい親例外の詳細としてラップすることで実装されます。たとえば、単一エンティティ・オブジェクトの複数の属性で属性レベルの検証ができない場合、これら複数のValidationExceptionオブジェクトは、RowValExceptionにラップされます。このラップ例外には、検証できなかった行の行キーが含まれています。トランザクションのコミット時に、コミット中に実行された検証を複数の行で渡せなかった場合、すべてのRowValExceptionオブジェクトは、包含するTxnValExceptionオブジェクトにラップされます。

カスタム・エラー処理コードを記述するときは、JboException基本例外クラスのgetDetails()メソッドを使用すると、内部にバンドルされている例外を再帰的に処理できます。


注意:

ここに記載されている例外クラスはすべて、oracle.jboパッケージのクラスです。


7.3 エンティティ・オブジェクトおよび属性への検証規則の追加

エンティティ・オブジェクトに検証規則を追加する手順は、ほとんどの検証規則と同じで、「検証ルールの追加」ダイアログを使用します。このダイアログは、「ビジネス・ルール」ページの「追加」アイコンをクリックして、概要エディタから開くことができます。

「検証ルールの追加」ダイアログを使用して規則を宣言的に定義すると、その規則定義が属性またはエンティティ・オブジェクトの有効な条件を指定することに注意する必要があります。実行時に、ユーザーが入力したエントリが規則定義に対して評価され、エントリが指定された基準を満たさない場合、エラーまたは警告が発せられます。たとえば、12より小さいか等しい必要のある属性に対して長さのバリデータを指定した場合、エントリが12文字よりも長いと検証が失敗し、エラーまたは警告が発行されます。

7.3.1 エンティティまたは属性への検証規則の追加方法

エンティティ・オブジェクトに宣言的な検証規則を追加するには、概要エディタの「ビジネス・ルール」ページを使用します。

検証規則を追加するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ナビゲーション・タブをクリックします。

  3. 検証規則を追加するオブジェクトを選択し、「追加」アイコンをクリックします。

    • エンティティ・オブジェクト・レベルで検証規則を追加するには、「エンティティ」を選択します。

    • 属性の検証規則を追加するには、「属性」を展開し、目的の属性を選択します。

    新しい検証規則を追加すると、「検証ルールの追加」ダイアログが表示されます。

  4. 「ルール・タイプ」ドロップダウン・リストから、目的の検証規則のタイプを選択します。

  5. ダイアログの設定を使用して新しい規則を構成します。

    このコントロールの内容は、選択する検証規則の種類によって異なります。様々な検証規則の詳細は、7.4項「組込みの宣言的な検証規則の使用」を参照してください。

  6. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。


    注意:

    Key ExistsおよびMethodエンティティ・バリデータの場合は、「検証実行」タブを使用して検証レベルを指定することもできます。


  7. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  8. 「OK」をクリックします。

7.3.2 エンティティまたは属性の検証規則の表示および編集方法

エンティティ・オブジェクトの概要エディタの「ビジネス・ルール」ページには、エンティティの検証規則とその属性がツリー・コントロールで表示されます。エンティティ全体に適用する検証規則を表示するには、「エンティティ」ノードを展開します。属性に適用する検証規則を表示するには、「属性」ノードを展開し、属性を展開します。

概要エディタの「ビジネス・ルール」ページに表示される検証規則には、定義した規則だけでなく、必須や精度などのデータベース制約も含まれます。検証規則を開いて編集するには、その規則をダブルクリックするか選択し、「編集」アイコンをクリックします。

7.3.3 検証規則の追加時の処理

エンティティ・オブジェクトに検証規則を追加すると、XMLコンポーネント定義が更新され、使用した規則と入力した規則プロパティを示すエントリが含まれます。たとえば、例7-2に示すように、レンジ検証規則をDiscountAmount属性に追加すると、XMLファイルにRangeValidationBeanエントリが含まれます。

例7-2 レンジ検証Bean

  <Attribute
    Name="DiscountAmount"
    IsNotNull="true"
    ColumnName="DISCOUNT_AMOUNT"
    . . . 
    <validation:RangeValidationBean
      xmlns="http://xmlns.oracle.com/adfm/validation"
      Name="DiscountAmount_Rule_0"
      ResId="DiscountAmount_RangeError_0"
      OnAttribute="DiscountAmount"
      OperandType="LITERAL"
      Inverse="false"
      MinValue="0"
      MaxValue="40"/>
    . . . 
  </Attribute>

実行時に、この規則はこの宣言情報に基づいてエンティティ・オブジェクトによって適用されます。

7.3.4 エンティティおよび属性の検証規則について

宣言的検証は、規則を配置した場所に応じて、エンティティ・レベルおよび属性レベルの両方の検証に適用されます。エンティティ・レベルの検証規則は、ユーザーが保留中の変更をコミットしようとした場合または行を移動しようとした場合に適用されます。また、ユーザーが関連属性の値を変更する場合、属性レベルの検証規則が適用されます。

Unique Keyバリデータ(7.4.1項「キー値が一意であることの確認方法」で説明している)はエンティティ・レベルでのみ使用できます。内部ではUnique Keyバリデータが属性レベルのバリデータとして機能します。したがって、ユーザーはバリデータが検証中のキーのキー属性をタブ・アウトすると、検証エラーが確認できます。エンティティの内部キャッシュには重複を含むことができず、属性値を設定するとこれに違反するため、この操作を行います。キャッシュの一貫性チェックは属性値の設定中に行われるため、このチェックは属性値を設定する際に行う必要があります。


ベスト・プラクティス:

1つの属性の有効性が1つ以上の他の属性に依存する場合は、属性の検証ではなくエンティティの検証を使用してこの規則を適用します。この処理を実行する例には次のようなものがあります。

  • ある属性を別のものと比較するCompare Validatorがある場合

  • 他の属性の値を調査して式のブランチ化を制御し、この他の属性の値に応じて様々な方法で属性を検証するExpression Validatorがある場合

  • 条件付き実行を使用する場合、および事前条件式に検証しているもの以外の属性が含まれている場合


エンティティ・オブジェクト・バリデータは、エンティティのいずれかが変更された場合に必ずトリガーされます。パフォーマンスを改善するには、規則内でロールを担う属性を示し、この種の属性が1つ以上変更された場合にのみ、規則をトリガーさせます。属性のトリガーの詳細は、7.6項「検証実行のトリガー」を参照してください。

7.3.5 値リストおよび属性検証規則について

開発者は、ユーザー・インタフェースでの選択リストの表示をサポートするために、ビュー・オブジェクトに対して値リスト(LOV)属性を定義できます。ビュー・オブジェクトのLOV属性は、表示する値を提供するために、データソース・ビュー・オブジェクトに依存します。LOV機能では問い合せるデータソースには有効な値のみが含まれていることを前提としているため、ユーザー・インタフェースに選択リストが表示される前に、データソース・ビュー・オブジェクト属性に対して定義されている検証規則は抑制されます。したがって、LOVを定義する開発者は、5.12項「ビュー・オブジェクト属性の値リスト(LOV)での作業」で説明しているように、データソース・ビュー・オブジェクトにより返される値リストには有効な値のみが含まれるようにする必要があります。

7.4 組込みの宣言的な検証規則の使用

組込みの宣言的な検証規則は、大部分のビジネス上のニーズを満たすことができます。このような規則は、コードの記述がないため実装が簡単です。検証のタイプとその使用方法を選択するには、ユーザー・インタフェース・ツールを使用します。

組込みの宣言的な検証規則を使用すると、次のことが可能です。

7.4.1 キー値の一意性を確認する方法

Unique Key Validatorは、エンティティ・オブジェクトの主キー値が常に一意であるかどうかを確認します。また、Unique Key Validatorは、その属性が代替キーとして定義されている場合、非主キー属性にも使用できます。代替キーの定義方法は、4.10.15項「代替キー値の定義方法」を参照してください。

キー属性値が変更されるたびに、この規則は、新しいキーがこのエンティティ・オブジェクト・クラスの他のエンティティ・オブジェクト・インスタンスに属していないことを検証します。(データベースの一意制約のビジネス・ロジック層に相当します。)エンティティ・オブジェクトの1つでキーが見つかった場合、TooManyObjectsExceptionがスローされます。検証チェックはエンティティ・キャッシュとデータベースの両方で行います。

一意キー検証を使用しても、データベースで重複行を防ぐことができない場合があります。また、2つのアプリケーション・モジュール・セッションが同時に同じキーのレコードを作成しようとする場合もあります。これを回避するには、適用する一意の制約に対して、データベースに一意索引を作成します。

キー値の一意性を確認するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、「エンティティ」フォルダを選択し、「追加」アイコンをクリックします。

  3. 「検証ルールの追加」ダイアログの「ルール・タイプ」・ドロップダウン・リストで「UniqueKey」を選択します。

  4. 「キー」ボックスで、主キーまたは代替キーを選択します。

  5. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。


    ベスト・プラクティス:

    Unique Key Validatorの事前条件の追加が可能ですが、ベスト・プラクティスではありません。Unique Key Validatorが起動できない場合でもキャッシュの一貫性チェックが実行されるため、エラーが返されます。通常は、バリデータおよびわかりやすいエラー・メッセージを追加するのが適切です。


  6. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  7. 「OK」をクリックします。

7.4.2 Unique Key Validatorの使用時の処理

Unique Key Validatorを使用すると、<UniqueKeyValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます。例7-3に、Unique Key ValidatorのXMLを示します。

例7-3 Unique Key ValidatorのXMLコード

  <validation:UniqueKeyValidationBean
    Name="PersonEO_Rule_1"
    KeyName="AltKey"
    ResId="PersonEO_Rule_1">
    <validation:OnAttributes>
      <validation:Item
        Value="Email"/>
    </validation:OnAttributes>
  </validation:UniqueKeyValidationBean>

7.4.3 比較に基づく検証方法

Compare Validatorは、エンティティ属性と値の論理比較を実行します。Compare Validatorの追加時に、演算子および比較対象を指定します。次のものを比較できます。

  • リテラル値

    Compare Validatorでリテラル値を使用すると、属性の値は指定したリテラル値と比較されます。この種類の比較を使用する場合は、データの型と書式を考慮することが重要です。リテラル値は、規則を適用するエンティティ属性のデータ型で指定した書式に準拠する必要があります。すべての場合において、型はエンティティ属性のタイプ・マッピングに対応します。

    たとえば、列タイプDATEの属性はoracle.jbo.domain.Dateクラスにマッピングされますが、これはjava.sql.TimeStampおよびjava.sql.Dateによって受け入れられるのと同じ書式で日付と時間を受け入れます。書式マスクを使用することにより、属性の値の書式が指定されたリテラルに一致するよう指定できます。エンティティ・オブジェクト属性タイプ・マッピングの詳細は、4.10.1項「エンティティ・オブジェクト属性のデータベースおよびJavaデータ型を設定する方法」を参照してください。 特定の型に求められる形式の詳細は、型クラスに関するJavadocを参照してください。

  • 問合せ結果

    このタイプのバリデータを使用すると、バリデータが実行されるたびにSQL問合せが実行されます。バリデータは問合せ結果から最初の行を取得し、比較する値として問合せの最初の列(その最初の行の)の値を使用します。この問合せは内部にバインド変数を所有できないため、この機能が使用されるのは、現行の行の値に依存しないデータの1つの行の1つの列を選択するときのみです。

  • ビュー・オブジェクト属性

    このタイプのバリデータを使用すると、バリデータが実行されるたびにビュー・オブジェクトのSQL問合せが実行されます。バリデータは問合せ結果から最初の行を取得し、比較する値としてその行から選択されたビュー・オブジェクト属性の値を使用します。ビュー・オブジェクトの名前付きバインド変数は値に関連付けできないので、そのような変数が利用できる値はデフォルト値のみです。したがって、この機能が使用されるのは、現行の行の値に依存しないデータの1つの行の属性を選択するときのみです。

  • ビュー・アクセッサ属性

    ビュー・アクセッサの定義時、検証ビュー・オブジェクトのバインド変数に行固有の値を割り当てることができます。

  • 式のオプションについては、7.5項「検証とビジネス・ルールへのGroovy式の使用」を参照してください。

  • エンティティ属性

    エンティティ属性オプションは、エンティティ・レベルのCompare Validatorに対してのみ利用可能です。

比較に基づいて検証するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「比較」を選択します。選択に応じて下位のフィールドは変わります。

  5. 適切な演算子を選択します。

  6. 「比較」リストで項目を選択し、選択項目に基づいて適切な比較値を指定します。

  7. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  8. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  9. 「OK」をクリックします。

図7-2は、エンティティ属性でエンティティレベルのCompareバリデータを使用する場合のダイアログを示しています。

図7-2 エンティティ・オブジェクト属性を使用したCompareバリデータ

ビュー・アクセッサ属性を使用するCompare Validatorの図

7.4.4 比較に基づく検証時の処理

Compare Validatorを使用すると、<CompareValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます。例7-4に、PersonEOエンティティ・オブジェクトのEmail属性のXMLコードを示します。

例7-4 Compare ValidatorのXMLコード

<validation:CompareValidationBean
  xmlns="http://xmlns.oracle.com/adfm/validation"
  Name="PersonEO_Rule_0"
  ResId="PersonEO_Rule_0"
  OnAttribute="Email"
  OperandType="ATTR"
  Inverse="false"
  CompareType="EQUALTO"
  CompareValue="ConfirmedEmail"/>

7.4.5 値リストを使用した検証方法

List Validatorにより、属性と値リスト(LOV)が比較されます。List Validatorの追加時に、選択対象のリストのタイプを指定します。

  • リテラル値 - バリデータは、エンティティ属性が値リスト内(指定された場合はリスト外)にあることを確認します。

  • 問合せ結果 - バリデータは、エンティティ属性が問合せの結果セットの最初の列内(指定された場合は列外)にあることを確認します。SQL問合せバリデータではバインド変数を使用できないので、表から問い合せる必要のある一定の小規模なリストでのみ使用する必要があります。問合せのすべての行はメモリーに取得されます。

  • ビューオブジェクト属性 - バリデータは、エンティティ属性がビュー属性内(指定された場合はビュー属性外)にあることを確認します。ビュー属性バリデータではバインド変数を使用できないため、表から問い合せる必要のある一定の小規模なリストでのみ使用する必要があります。問合せのすべての行はメモリーに取得されます。

  • ビュー・アクセッサ属性 - バリデータは、エンティティ属性がビュー・アクセッサ属性内(またはビュー・アクセッサ属性外)にあることを確認します。ビュー・アクセッサにはバインド変数が利用可能で、ユーザー・インタフェース上にLOVを作成するとビュー・アクセッサが必要になるため、ビュー・アクセッサはおそらく最も便利なオプションです。


ベスト・プラクティス:

Listバリデータの使用時は、ビュー・アクセッサ上でビュー基準を定義し、適宜ビュー・データのフィルタが行えるので、ビュー・アクセッサが最も便利です。一般的に、ビュー属性でLOVを定義する場合は、ビュー基準を設定してビュー・アクセッサを使用します。


値リストを使用して検証するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「リスト」を選択します。

  5. 「属性」リストで、適切な属性を選択します。

  6. 「演算子」フィールドで、包含的リストか排他的リストかに応じて「In」または「NotIn」を選択します。

  7. 「リスト・タイプ」フィールドで、適切なリスト・タイプを選択します。

  8. 選択したリストのタイプに応じて、リスト値(新規行の各値)の入力、SQL問合せの入力、またはビュー・オブジェクト属性かビュー・アクセッサ属性の選択ができます。

  9. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  10. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  11. 「OK」をクリックします。

図7-3は、ビュー・アクセッサ属性でListバリデータを使用する場合のダイアログを示しています。

図7-3 ビュー・アクセッサ属性を使用するListバリデータ

SQL問合せを使用するList Validatorの図

7.4.6 リスト値を使用した検証時の処理

リスト値を使用して検証すると、<ListValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます。例7-5に、Listバリデータのビュー・アクセッサ属性を使用するPaymentOptionEO.PaymentTypeCode属性を示します。

例7-5 List ValidatorのXMLコード

<validation:ListValidationBean
   xmlns="http://xmlns.oracle.com/adfm/validation"
   Name="PaymentTypeCode_Rule_0"
   ResId="PaymentTypeCode_Rule_0"
   OnAttribute="PaymentTypeCode"
   OperandType="VO_USAGE"
   Inverse="false"
   ViewAccAttrName="Value"
   ViewAccName="PaymentTypesVA"/>

7.4.7 List Validatorについて

List Validatorは、比較的小さい値セットに対して属性を検証するためのものです。「問合せ結果」または「ビュー・オブジェクト属性」タイプのリスト検証を選択する場合、検証対象の属性値がリスト内の属性と一致するかどうかを検証するためにメモリー内スキャンが実行される前に、問合せ結果のすべての行が取得されることに注意してください。バリデータのSQLまたはビュー・オブジェクト問合せによって実行される問合せでは、問合せのWHERE句で検証される値は参照されません。

ユーザーが入力した製品コードが、膨大な量の製品が含まれる表に存在するかどうかを判別する必要がある場合、検証規則を使用することは効率的ではありません。かわりに、データベースに対して目的の検証問合せを実行するためにビュー・オブジェクトを使用してSQLベースの検証を効率的に実行するための技術は、8.5項「検証でのビュー・オブジェクトの使用」を参照してください。5.12.10.2項「バリデータを使用した属性値の検証」も参照してください。

また、比較する属性がキーの場合、リスト値の検証よりもKey Exists Validatorが効率的であり、これらの選択を翻訳する必要がある場合、リテラルの選択のかわりに静的ビュー・オブジェクトを使用します。

7.4.8 値が特定の範囲内にあることを確認する方法

Range Validatorは、エンティティ属性と値の範囲の論理比較を実行します。Range Validatorの追加時に、最小および最大のリテラル値を指定します。Range Validatorは、エンティティ属性の値が範囲内(指定された場合は、範囲外)にあることを検証します。

最小および最大値を動的に算出する必要がある場合や、エンティティの他の属性を参照する必要がある場合は、Script Expression Validatorを使用し、Groovy式を指定します。詳細は、3.6.1項「Groovy式でのビジネス・コンポーネント・オブジェクトの参照」3.6.3項「Groovy式でのビジネス・コンポーネント属性値の操作」を参照してください。

特定の範囲内を検証するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「範囲」を選択します。

  5. 「属性」リストで、適切な属性を選択します。

  6. 「演算子」フィールドで、「Between」または「NotBetween」を選択します。

  7. 「最小値」および「最大値」フィールドに適切な値を入力します。

  8. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  9. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  10. 「OK」をクリックします。

7.4.9 Range Validatorの使用時の処理

Rangeを検証すると、<RangeValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます。例7-6に、与信限度が最小値0で最大値10,000のPersonEO.CreditLimit属性を示します。

例7-6 Range ValidatorのXMLコード

<validation:RangeValidationBean
  Name="CreditLimit_Rule_0"
  ResId="CreditLimit_Rule_0"
  OnAttribute="CreditLimit"
  OperandType="LITERAL"
  Inverse="false"
  MinValue="0"
  MaxValue="10000"/>

7.4.10 バイトまたは文字数に対する検証方法

Length Validatorは、属性値の文字列長(文字またはバイト)が、指定した数より小さい、等しい、それより大きい、またはその範囲内かどうかを検証します。

バイトまたは文字数を検証するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「長さ」を選択します。

  5. 「属性」リストで、適切な属性を選択します。

  6. 「演算子」フィールドで、値を評価する方法を選択します。

  7. 「比較タイプ」フィールドで、「バイト」または「文字」を選択し、長さを入力します。

  8. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  9. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  10. 「OK」をクリックします。

7.4.11 バイトまたは文字数に対する検証時の処理

長さを使用して検証すると、<LengthValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます(例7-7を参照)。たとえば、ユーザーがパスワードまたはPINを入力するフィールドがあり、アプリケーションによってそれが6文字以上、10文字以下であることを検証するとします。Length ValidatorでBetween演算子を使用し、最小値および最大値をそれぞれ設定します。

例7-7 2つの値の長さの検証

    <validation:LengthValidationBean
      OnAttribute="pin"
      CompareType="BETWEEN"
      DataType="CHARACTER"
      MinValue="6"
      MaxValue="10"
      Inverse="false"/>

7.4.12 正規表現を使用した検証方法

Regular Expression Validatorは、Java正規表現によって指定されたマスクに対して属性値を比較します。

メタデータでパーソナライズできる式を作成する場合は、Script Expression Validatorを使用できます。詳細は、7.5項「検証とビジネス・ルールへのGroovy式の使用」を参照してください。

正規表現を使用して検証する手順:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「正規表現」を選択します。

  5. 「演算子」フィールドで、「一致」または「不一致」を選択します。

  6. 事前定義された式(ある場合)を使用するには、ドロップダウン・リストから選択して「パターンの使用」をクリックします。事前定義された式を使用しない場合は、表示されているフィールドに独自の正規表現を記述します。


    注意:

    事前定義された式のリストに独自の式を追加することもできます。事前定義された式を追加するには、JDeveloperシステム・ディレクトリのBC4JサブディレクトリにあるPredefinedRegExp.propertiesファイル(例: C:\Documents and Settings\username\Application Data\JDeveloper\system##\o.BC4J\PredefinedRegExp.properties)にエントリを追加します。


  7. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  8. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  9. 「OK」をクリックします。

図7-4は、Regular Expression Validatorを選択して、Email属性が事前定義されたEmail Address式に一致することを検証する場合のダイアログを示しています。

図7-4 電子メール・アドレスを照合するRegular Expression Validator

電子メール・アドレスを照合するRegular Expression Validatorの図

7.4.13 正規表現を使用した検証時の処理

正規表現を使用して検証すると、<RegExpValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます。例7-8は、正規表現に一致する必要のあるEmail属性を示しています。

例7-8 Regular Expression ValidatorのXMLコード

<validation:RegExpValidationBean
  Name="Email_Rule_0"
  OnAttribute="Email"
  Pattern="[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}"
  Flags="CaseInsensitive"
  Inverse="false"/>

7.4.14 Average、Count、またはSumを使用したコレクションの検証方法

コレクションのAverage、Count、Sum、Min、またはMaxに対してコレクション検証を使用できます。このバリデータは、エンティティ・レベルでのみ使用できます。このバリデータは、子エンティティ(アソシエーションの多数の端)に対するエンティティ・アクセッサを介した、関連エンティティのコレクションに対する集計計算の検証に便利です。Collection Validatorを定義するには、アソシエーション・アクセッサを選択する必要があります。

集約計算を使用した検証方法は次のとおりです。

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、「エンティティ」フォルダを選択し、「追加」アイコンをクリックします。

  3. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「コレクション」を選択します。

  4. 「操作」フィールドで、コレクションで比較に実行する操作(Sum、Average、Count、MinまたはMax)を選択します。

  5. 検証に使用する適切なアクセッサと属性を選択します。

    コンポジット・アソシエーション・アクセッサを選択する必要があります。この種のアクセッサのプロパティは、ドロップダウン・リストに表示されます。

  6. 演算子を指定し、比較タイプと値を指定します。

  7. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  8. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  9. 「OK」をクリックします。

7.4.15 コレクション検証の使用時の処理

Collection Validatorを使用して検証すると、<CollectionValidationBean>タグがエンティティ・オブジェクトのXMLファイルに追加されます(例7-9を参照)。

例7-9 Collection ValidatorのXMLコード

<validation:CollectionValidationBean
    Name="OrderEO_Rule_0"
    OnAttribute="OrderTotal"
    OperandType="LITERAL"
    Inverse="false"
    CompareType="LESSTHAN"
    CompareValue="5"
    Operation="sum"/>

7.4.16 キーの存在の判別方法

Key Exists Validatorは、キー値(主キー、外部キー、代替キーのいずれか)が存在するかどうか判別するために使用されます。

Key Exists Validatorの使用には、次のようないくつかの利点があります。

  • Key Exists Validatorは、最初にキャッシュをチェックし、必要な場合にのみデータベースをチェックするため、パフォーマンスが向上します。

  • Key Exists Validatorはキャッシュを使用するため、現行トランザクションに追加されているが、まだデータベースにコミットされていないキー値を検出します。たとえば、新規のDepartmentを追加してから、そこにEmployeeをリンクします。

値の存在を判別するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」リストで、「キーの存在」を選択します。

  5. 検証ターゲットのタイプ(「エンティティ・オブジェクト」「ビュー・オブジェクト」またはビュー・アクセッサ」)を選択します。

    このエンティティ属性を使用するすべてのビュー・オブジェクトにKey Exists Validatorを使用する場合は、「エンティティ・オブジェクト」を選択します。

  6. 検証ターゲットに応じて、アソシエーションまたはキー値を選択できます。

    「検証ターゲット属性」リストにない属性を検索している場合は、キー値として定義されていない可能性があります。代替キーを作成するには、4.10.15項「代替キー値の定義方法」を参照してください。

  7. 必要に応じて、「検証実行」タブをクリックして、依存属性や検証レベル(エンティティまたはトランザクション)などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  8. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  9. 「OK」をクリックします。

図7-5は、PersonEOエンティティ・オブジェクトに入力したMembershipIdMembershipBaseEOエンティティ・オブジェクトに存在するかどうかを検証するKey Exists Validatorを示しています。

図7-5 エンティティ属性に対するKey Exists Validator

エンティティ属性に対するKey Exists Validatorの図

7.4.17 Key Exists Validatorの使用時の処理

Key Exists Validatorを使用すると、<ExistsValidationBean>タグがエンティティ・オブジェクトのXMLファイルに作成されます(例7-10を参照)。

例7-10 アソシエーションでのKey Exists Validatorの使用

<validation:ExistsValidationBean
      Name="MembershipId_Rule_0"
      ResId="MembershipId_Rule_0"
      OperandType="EO"
      AssocName= "oracle.fodemo.storefront.entities.associations.PersonsMembershipsBaseFkAssoc"/>

7.4.18 宣言的バリデータとビュー・アクセッサについて

宣言的バリデータを使用する場合は、想定される入力値で検証がどのように実行されるかを考慮する必要があります。宣言的バリデータとビュー・アクセッサを組み合せることにより、簡単かつ強力なコーディングの代用として機能します。ただし、これらを組み合せると強力になる反面、データ構成がパフォーマンスに与える影響も考慮する必要があります。

次のようなシナリオを検討します。

  • Product属性とRequestType属性を持つServiceRequestEOエンティティ・オブジェクト、およびRequestTypeVOビュー・オブジェクトへのアクセスを可能にするビュー・アクセッサ

  • Product属性をバインド・パラメータとして指定する問合せを持つRequestTypeVOビュー・オブジェクト

RequestTypeの有効なリストは、Productによって変わります。このため、RequestType属性を検証するには、ビュー・アクセッサを使用するList Validatorを使用します。

最初に、新規サービス・リクエストのセットを追加します。最初のサービス・リクエスト(行)に対して、List ValidatorはProduct属性の値をビュー・アクセッサに追加して実行します。次に、後続の各サービス・リクエストに対して、Product属性の新しい値と現時点でバインドされている値を比較します。

  • Productの値が一致する場合、現在のRowSetオブジェクトは維持されます。

  • Productの値が変更されている場合、新しい値がバインドされ、ビュー・アクセッサが再実行されます。

次に、想定される入力データの構成を検討します。たとえば、入力データに同じ製品が複数回現れるとします。受注品のデータを検証すると、次のようになっているとします。

  1. ドライヤー(最初の問合せ)

  2. 洗濯機(ビュー・アクセッサを再実行)

  3. 食器洗浄機(ビュー・アクセッサを再実行)

  4. 洗濯機(ビュー・アクセッサを再実行)

  5. ドライヤー(ビュー・アクセッサを再実行)

この場合、バリデータは問合せを5回実行し、個別の行セットを3つ取得します。また、RequestTypeVOORDER BY句を追加して、Product別にソートすることもできます。この場合、バリデータは洗濯機とドライヤーに対して問合せをそれぞれ1回のみ実行します。

  1. 食器洗浄機(最初の問合せ)

  2. ドライヤー(ビュー・アクセッサを再実行)

  3. ドライヤー

  4. 洗濯機(ビュー・アクセッサを再実行)

  5. 洗濯機

このサイズのデータセットでは違いがあまり出ませんが、データセットのサイズが膨大になりユーザー数が多くなると、その差が大きな問題となります。ORDER BY句ですべての問題に対応できるとはかぎりませんが、この例は、データ構成がパフォーマンスにどのように影響を与えるかを示しています。

7.5 検証とビジネス・ルールへのGroovy式の使用

Groovy式は、エンティティ・オブジェクトのXML定義に格納されている、Javaのようなスクリプト・コードです。Groovy式がXMLに格納されているため、エンティティ・オブジェクトのJavaファイルに対するアクセス権がなくても式の値を変更できます。実行時でも値の変更や指定ができます。

エンティティ・オブジェクトのビジネス・ロジックでのGroovyスクリプトの使用方法の詳細は、3.6項「Groovyサポートの概要」を参照してください。

7.5.1 Groovy検証式でのエンティティ・オブジェクト・メソッドの参照方法

現在のオブジェクトのsourceプロパティを使用すると、現在のエンティティ・インスタンスでメソッドをコールできます。sourceプロパティでは、検証対象のエンティティ・インスタンスにアクセスできます。

メソッドがブール型以外で、メソッド名が引数なしのgetXyzAbc()の場合、XyzAbcという名前のプロパティのようにその値にアクセスします。ブール値プロパティの場合は、同じ条件が当てはまりますが、JavaBeanのgetterメソッドの命名パターンが変更され、getXyzAbc()ではなくisXyzAbc()を再認識します。エンティティ・オブジェクトのメソッドがJavaBeanのgetterメソッドの命名パターンに一致しない場合や、1つ以上の引数を使用する場合は、完全名を使用したメソッドのようにコールする必要があります。

たとえば、例7-11に示すように、4つのメソッドを持つエンティティ・オブジェクトがあるとします。

例7-11 サンプルのエンティティ・オブジェクト・メソッド

public boolean isNewRow() {
 System.out.println("## isNewRow() accessed ##"); 
 return true; 
} 
 
public boolean isNewRow(int n) {
 System.out.println("## isNewRow(int n) accessed ##");
 return true;
}
 
public boolean testWhetherRowIsNew() {
 System.out.println("## testWhetherRowIsNew() accessed ##"); 
 return true; 
}
 
public boolean testWhetherRowIsNew(int n) {
 System.out.println("## testWhetherRowIsNew(int n) accessed ##");
 return true;
} 

次のGroovy検証条件では、例7-12に示すように、すべてをトリガーし、その内の1つは2回トリガーされます。

例7-12 サンプルのメソッドをコールするGroovyスクリプト

newRow && source.newRow && source.isNewRow(5) && source.testWhetherRowIsNew() && source.testWhetherRowIsNew(5)

この例を実行してエンティティ検証を適用すると、例7-13に示すように、診断結果がログ・ウィンドウに表示されます。

例7-13 サンプルのGroovyスクリプトの出力結果

## isNewRow() accessed ##
## isNewRow() accessed ##
## isNewRow(int n) accessed ##
## testWhetherRowIsNew() accessed ##
## testWhetherRowIsNew(int n) accessed ##

名前がJavaBeansプロパティのgetterメソッドの命名パターンに一致するメソッドの参照では、構文にほとんど差がありません。newRowsource.newRowは、両方とも、引数のないブール値のJavaBeans getterスタイル・メソッドにアクセスします。testWhetherRowIsNewメソッドは、JavaBeansのgetterメソッドの命名パターンに一致せず、2番目のisRowNewメソッドは引数を使用するため、完全名を使用するメソッドのようにコールする必要があります。

7.5.2 true/false式を使用した検証方法

Groovy式を使用してtrue/false文を返すことができます。Script Expression Validatorでは、必ず式がtrueまたはfalseを返す必要があり、そうでなければadf.error.raise/warn()メソッドがコールされます。この機能の一般的な用途は、属性値の検証です(アカウント番号が有効であるかの確認など)。


注意:

adf.error.raise()メソッドを使用することにより(単純にtrueまたはfalseを返すかわりに)、ユーザーに表示するメッセージ・テキストを定義でき、エンティティレベル・バリデータを特定の属性に関連付けることができます。詳細は、7.7.3項「Groovyを使用して条件付きでエラー・メッセージを呼び出す方法」を参照してください。


true/false式を使用して検証するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、バリデータを追加する場所を選択します。

    • エンティティ・レベルのバリデータを追加するには、「エンティティ」フォルダを選択します。

    • 属性レベルのバリデータを追加するには、「属性」フォルダを展開し、適切な属性を選択します。

  3. 「追加」アイコンをクリックします。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「スクリプト式」を選択します。

  5. 表示されているフィールドに検証式を入力します。

  6. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などの規則の実行基準を入力できます。詳細は、7.6項「検証実行のトリガー」を参照してください。

  7. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。詳細は、7.7項「検証エラー・メッセージの作成」を参照してください。

  8. 「OK」をクリックします。

例7-14のサンプル・コードは、PaymentOptionEOエンティティ・オブジェクトからの出力です。コードは、広範に使用されているチェックサムのLuhnアルゴリズムに基づいて口座番号を検証します。

例7-14 式を使用した口座番号の検証

<validation:ExpressionValidationBean
  Name="AccountNumber_Rule_0"
  OperandType="EXPR"
  Inverse="false">
  <OnCondition>
    <![CDATA[PaymentTypeCode=='CC']]>
  </OnCondition>
  <MsgIds>
   <Item
    Value="PaymentOption_AccountNumber"/>
  </MsgIds>
  <TransientExpression>
   <![CDATA[
    String acctnumber = newValue;
     sumofdigits = 0;
     digit = 0;
     addend = 0;
     timesTwo = false;
     range = acctnumber.length()-1..0
      range.each {i ->
      digit = Integer.parseInt (acctnumber.substring (i, i + 1));
      if (timesTwo) {
       addend = digit * 2;
       if (addend > 9) {
        addend -= 9;
       }
      }
      else {
       addend = digit;
      }
      sumofdigits += addend;
      timesTwo = !timesTwo;
     }
     modulus = sumofdigits % 10;
     return modulus == 0;
   ]]>
  </TransientExpression>
</ExpressionValidationBean>

7.5.3 Groovy式の追加時の処理

Groovy式を作成すると、エンティティ・オブジェクトのXMLコンポーネントに保存されます。例7-15に、PersonEO.xmlファイルのRegisteredDate属性を示します。Groovy式は、<TransientExpression>タグによってラップされます。

例7-15 PersonEOエンティティ・オブジェクトのRegisteredDate属性のXMLコード

<Attribute
    Name="RegisteredDate"
    IsUpdateable="true"
    ColumnName="REGISTERED_DATE"
    Type="oracle.jbo.domain.Date"
    ColumnType="DATE"
    SQLType="DATE"
    TableName="PERSONS">
    <DesignTime>
      <Attr Name="_DisplaySize" Value="7"/>
    </DesignTime>
    <validation:ExpressionValidationBean
      Name="RegisteredDate_Rule_0"
      OperandType="EXPR"
      Inverse="false">
      <MsgIds>
        <Item
          Value="RegisteredDate_Rule_0"/>
      </MsgIds>
      <TransientExpression>
        <![CDATA[
newValue <= (new java.sql.Timestamp(System.currentTimeMillis()))
         ]]>
      </TransientExpression>
    </ExpressionValidationBean>
  </Attribute>

このタグはいくつかの形式のいずれかを利用できます。一部のGroovy式では、<TransientExpression>タグは、<ExpressionValidationBean>タグによってもラップされます。図7-6は、「検証規則の編集: {0}」ダイアログの検証式を示しています。

図7-6 PersonEOエンティティ・オブジェクトのRegisteredDate属性の検証式

「検証規則の編集: {0}」ダイアログの検証式の図

7.6 検証実行のトリガー

JDeveloperでは、検証をトリガーする属性を選択できるため、トリガー属性のいずれかの内容が保証されない場合にのみ検証実行が発生します。JDeveloperの以前のリリースでは、全体としてのエンティティの内容が保証されない場合は常に属性に対してエンティティ・レベルのバリデータが起動されていました。この機能については、7.6.1項「検証を起動する属性の指定方法」を参照してください。

JDeveloperでは、バリデータ実行の事前条件を指定することもできます(7.6.3項「検証の事前条件の設定方法」を参照)また、トランザクション・レベルの検証を設定することもできます(7.6.4項「トランザクション・レベルの検証の設定方法」を参照)。

7.6.1 検証を起動する属性の指定方法

エンティティ・レベルでバリデータを定義する場合、変更時にバリデータの実行をトリガーする、エンティティ・オブジェクトの1つ以上の属性を選択するオプションがあります。


注意:

1つの属性の有効性が別の属性に依存する場合、検証は属性の検証ではなくエンティティの検証として実行する必要があります。エンティティ・レベルや属性レベルで検証実行の順序を設定できます。


依存属性を1つ以上指定しないと、エンティティの内容が保証されていない場合にバリデータが常に起動します。必要な場合にのみ検証を実行することで、アプリケーションをより高性能にします。

検証を起動する属性を指定するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、検証規則を選択して「編集」アイコンをクリックします。

  3. 「検証規則の編集: {0}」ダイアログで、「検証実行」タブをクリックします。

  4. 検証を起動する属性を選択します。

  5. 「OK」をクリックします。

たとえば、Fusion Order DemoアプリケーションのStoreFrontモジュールでは、OrderEOエンティティ・オブジェクトに、GiftwrapMessage属性の長さを制限するエンティティレベル・バリデータがあります。図7-7に示すように、このバリデータはGiftwrapMessage属性またはGiftwrapFlag属性の変更時にのみ、エンティティ・オブジェクト上で実行するように設定されています。

図7-7 「検証ルールの編集」ダイアログの「検証実行」タブでの属性のトリガー

「検証ルール」ダイアログでの属性のトリガーのイメージ

7.6.2 属性のトリガーによる検証実行制約時の処理

「検証規則の編集」ダイアログの「検証実行」タブでトリガー属性を指定すると、JDeveloperは<OnAttributes>タグを、エンティティ・オブジェクトのXMLファイルのバリデータ定義に追加します。例7-16は、Fusion Order DemoアプリケーションのStoreFrontモジュールの、OrderEOエンティティ・オブジェクトのエンティティレベル・バリデータのXMLコードを示しています。

例7-16 XML検証コードのOnAttributes要素

<LengthValidationBean
  xmlns="http://xmlns.oracle.com/adfm/validation"
  Name="OrderEO_Rule_0"
  OnAttribute="GiftwrapMessage"
  CompareType="GREATERTHANEQUALTO"
  DataType="CHARACTER"
  CompareLength="1"
  Inverse="false"
  ResId="GiftMessage_Required_Error_0">
  <OnAttributes>
    <Item Value="GiftwrapMessage"/>
    <Item Value="GiftwrapFlag"/>
  </OnAttributes>
  <OnCondition>
    <![CDATA[GiftwrapFlag == 'Y']]>
  </OnCondition>
</LengthValidationBean>

7.6.3 検証の事前条件の設定方法

「検証実行」タブ(検証規則の追加/編集ダイアログ)で、事前条件として機能するGroovy式を追加できます。「条件付実行式」ボックスに式を入力すると、条件がTrueに評価された場合のみ、バリデータが実行されます。


ベスト・プラクティス:

Unique Key Validatorの事前条件の追加が可能ですが、ベスト・プラクティスではありません。Unique Key Validatorが起動できない場合でもキャッシュの一貫性チェックが実行されるため、エラーが返されます。通常は、バリデータおよびわかりやすいエラー・メッセージを追加するのが適切です。


7.6.4 トランザクション・レベルの検証の設定方法

トランザクション・レベル(エンティティ・レベルではなく)での検証は、すべてのエンティティ・レベルの検証の実行後に実行されます。このため、バリデータがプロセスの終了時に実行されることを確認する場合に便利です。

さらにKey Existsバリデータをトランザクション・レベルで実行すると、エンティティごとではなく、トランザクション内の全エンティティ(同じ型の)に対して1度だけ実行されるので、 大量のトランザクションでは高いパフォーマンスが得られます。これにより、バリデータをデータベースに使用する場合はパフォーマンスの改善につながります。


注意:

トランザクション・レベルの検証は、Key ExistsおよびMethodエンティティ・バリデータにのみ適用できます。


エンティティ・レベルまたはトランザクション・レベルの検証を指定するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、エンティティ・レベルの検証規則を選択し、「編集」アイコンをクリックします。

  3. 「検証規則の編集: {0}」ダイアログで、「検証実行」タブをクリックします。

  4. 「エンティティ・レベルで実行」または「トランザクション・レベルの遅延実行」を選択します。

  5. 「OK」をクリックします。

7.6.5 検証実行の順序について

属性の検証順序は制御できません。エンティティ定義の順番で常に検証されます。特定の属性(またはエンティティ)の検証の順番を指定することはできますが、属性自体の順番を変更することはできません。

7.7 検証エラー・メッセージの作成

検証エラー・メッセージはユーザーにとって重要な情報であり、メッセージは不具合やその修正方法を伝達する必要があります。

7.7.1 検証エラー・メッセージの作成方法

検証規則を作成または編集する場合、ユーザーがエラーの原因を判断するために有用な文章を入力します。

検証エラー・メッセージを作成するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタの「ビジネス・ルール」ページで、検証規則を選択して「編集」アイコンをクリックします。

  3. 「検証規則の編集: {0}」ダイアログで、「失敗処理」タブをクリックします。

  4. 「メッセージ・テキスト」フィールドで、エラー・メッセージを入力します。

    メッセージ・バンドル・ファイルにエラー・メッセージを定義することもできます。定義済のエラー・メッセージを選択する場合や、メッセージ・バンドル・ファイルに新しいエラー・メッセージを定義する場合は、「メッセージの選択」アイコンをクリックします。


    注意:

    Script Expression Validatorでは、複数のエラー・メッセージを入力できます。これは、条件によって異なるエラーメッセージや警告メッセージを検証スクリプトで戻す場合に便利です。詳細は、7.7.3項「Groovyを使用して条件付きでエラー・メッセージを呼び出す方法」を参照してください。


  5. 必要に応じて、メッセージの本文にメッセージ・トークンを含めることができます。メッセージ・トークンは、「トークン・メッセージ式」リストで定義します。

    図7-8は、メッセージ・トークンを含むPaymentOptionEOエンティティ・オブジェクトの検証規則の失敗メッセージを示しています。この機能の詳細は、7.7.4項「エラー・メッセージにGroovy式を埋め込む方法」を参照してください。

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

7.7.2 検証メッセージのローカライズ方法

エラー・メッセージは翻訳可能文字列であり、エンティティ・オブジェクトのメッセージ・バンドル・クラスの翻訳可能UIコントロール・ヒントと同じように管理されます。メッセージ・バンドル・クラス内の定義済規則のエラー・メッセージを表示するには、そのバリデータに関するXMLコンポーネント定義エントリのResIdプロパティに対応するメッセージ・バンドルのStringキーを探します。たとえば、例7-17は、NAME_CANNOT_BEGIN_WITH_Uキーがデフォルト・ロケールのエラー・メッセージとともに表示されるメッセージ・バンドルを示しています。

例7-17 検証エラー・メッセージが含まれるメッセージ・バンドル

package devguide.advanced.customerrors;
import java.util.ListResourceBundle;

public class CustomMessageBundle extends ListResourceBundle {
  private static final Object[][] sMessageStrings = new String[][] {
  // other strings here
  {"NAME_CANNOT_BEGIN_WITH_U", "The name cannot begin with the letter u!"},
  // other strings here
  };
  // etc.
}

アプリケーションのリソース・バンドルは、リスト・リソース・バンドル(例7-17に示すように)、プロパティ・バンドル、またはXLIFFリソース・バンドルとして作成できます。変換可能な文字列使用の詳細は、4.7項「リソース・バンドルの使用」を参照してください。

7.7.3 Groovyを使用して条件付きでエラー・メッセージを呼び出す方法

adf.error.raise()およびadf.error.warn()メソッドを使用して、Groovy式の分岐に応じて様々なエラー・メッセージを条件付きで呼び出すことができます。たとえば、属性値がxの場合は次のように検証し、検証が失敗した場合はエラーメッセージAを呼び出し、一方、属性値がyの場合は別の検証を実行し、検証が失敗した場合はエラーメッセージBを呼び出します。

式でfalseが戻される(raise()メソッドを使用して特定のエラー・メッセージが呼び出されるのに対して)場合、バリデータは、そのバリデータに関連付けられた最初のエラー・メッセージをコールします。

raise()メソッドの構文は必須パラメータを1つ(メッセージ・バンドルから使用するためのmsgId)利用し、オプションでattrNameパラメータを利用することができます。AttrNameに渡すと、検証がエンティティに割り当てられている場合でも、エラーはその属性に関連付けられます。

例外をスローするか、処理を継続するかに応じて、adf.error.raise()またはadf.error.warn()のいずれのメソッドも使用できます(7.8項「検証例外の重大度レベルの設定」を参照)。

7.7.4 エラー・メッセージにGroovy式を埋め込む方法

バリデータのエラー・メッセージには、実行時にサーバーによって解決できる埋込み式を含めることができます。この機能にアクセスするには、Groovy式の結果を表示させるエラー・メッセージ・テキストに名前付きトークン{#}({2}{errorParam}など)を入力するのみです。

「検証規則の編集: {0}」ダイアログの「失敗処理」タブで、エラー・メッセージのテキストにトークンを入力すると、ダイアログの下部の「トークン・メッセージ式」表で行が表示され、トークンのGroovy式を入力できます。図7-8は、メッセージ・トークンを含むPaymentOptionEOエンティティ・オブジェクトの検証規則の失敗メッセージを示しています。

図7-8 失敗メッセージでのメッセージ・トークンの使用

トークンを使用したメッセージを表示した失敗処理」タブの図

図7-8に示された式は、指定したフィールドのラベルを返すGroovy式です。Groovy式を使用して属性値やその他のビジネス・コンポーネント・オブジェクトにアクセスすることもできます。Fusion Order DemoアプリケーションのStoreFrontモジュールのPaymentOptionEOエンティティ・オブジェクトのRoutingIdentifier属性に対するRuleバリデータのように、Groovy式newValueを使用して入力した値を返すことができます。

ビュー・アクセッサから値を取得するためのGroovy構文は、accessorName.currentRow.AttributeNameです。たとえば、Groovy式MyEmpAccessor.currentRow.Jobは、MyEmpAccessorビュー・アクセッサの現在の行のJob属性値を返します。

例7-18のように複雑なGroovy式を使用して、AddressUsageEOエンティティ・オブジェクト内のOwnerTypeCode属性のList検証規則のエラー・メッセージに式を表示することもできます。

例7-18 OwnerTypeCode検証エラー・メッセージ内のGroovyスクリプト

def ownertypevalue = [] 
while ( AddressOwnerTypesVA.hasNext() ) { 
AddressOwnerTypesVA.next()
  ownertypevalue.add(AddressOwnerTypesVA.currentRow.Value) 
} 
return ownertypevalue

Groovyを使用してビジネス・コンポーネントにアクセスする方法の詳細は、3.6項「Groovyサポートの概要」を参照してください。

7.8 検証例外の重大度レベルの設定

検証例外の重大度レベルについて、「情報警告」および「エラー」の2つのレベルを設定できます。重大度レベルを「情報警告」に設定すると、エラー・メッセージが表示されますが、処理は継続します。検証レベルを「エラー」に設定すると、エラーが修正されるまでユーザーは処理を続行できません。

通常、検証例外には「エラー」レベルを使用するため、これがデフォルト設定です。ただし、ユーザーが特定の機密取扱い資格を保持する場合は、情報警告メッセージを実装できます。たとえば、店長は事務員が同じことをした場合に、エラーとして表示されるように変更できます。

検証例外の重大度レベルを設定するには、「検証ルールの追加」ダイアログの「失敗処理」タブを使用します。

検証例外の重大度レベルを設定するには:

  1. アプリケーション・ナビゲータで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 「ビジネス・ルール」ページで、既存の検証規則を選択して「編集」アイコンをクリックするか、「追加」アイコンをクリックして新規の規則を作成します。

  3. 検証規則の追加/編集ダイアログで、「失敗処理」タブをクリックし、「エラー」または「情報警告」のいずれかのオプションを選択します。

  4. 「OK」をクリックします。

7.9 SQLでのバルク検証

データ同期プログラムなどのバッチロード・アプリケーションのパフォーマンスを向上させるため、ADFフレームワークでは、主キー(代替キーを含む)および外部キーにバルク検証を採用しています。

トランザクションがコミットするまで検証を遅延するようにKey Exists Validatorを構成している場合や、ADFビジネス・コンポーネントのサービス・レイヤーのprocessXXXメソッドで行が更新または挿入されている場合、検証キャッシュが事前ロードされます。この動作は通常の行ごとの導出および検証ロジックを使用しますが、データベースに問い合せる前にメモリー・キャッシュをチェックする検証ロジックを使用します。パフォーマンスは、インバウンド・データに基づいてバルクSQL操作を使用するメモリー・キャッシュの事前ロードによって向上します。