Bean のメソッド

このセクションでは、各必須 Bean メソッドの背後にある処理とパーシスタンス ロジックについて詳しく説明します。

ejbCreate および ejbPostCreate

Bean インスタンスを作成する場合、コンテナでは Bean の ejbCreate メソッドを呼び出します。ejbCreate メソッドによって、渡された引数を検証し、Bean 変数を使用して SQL パラメータを置き換える場合は、渡された引数を Bean インスタンス変数にコピーできます。次に、コンテナでは、createSQL ステートメントを実行します。通常はこの createSQL ステートメントによってデータベースに行が挿入されます。プライマリ キーを持つ行がすでに存在する場合は、DuplicateKeyException が返されます。

次に、コンテナでは、Bean の ejbPostCreate メソッドを呼び出します。

コンテナで実行される一連の手順は次のとおりです。

  1. Bean インスタンスの ejbCreate を呼び出します。
  2. createSQL ステートメントを実行します。
  3. プライマリ キーがデータベースに存在している場合は、
    javax.ejb.DuplicateKeyException が返されます。
  4. postCreateSQL を実行し、ejbPostCreate メソッドを呼び出します。

公開記述子で Bean 変数を使用して SQL パラメータを置き換える場合は、次の例に示すように、ejbCreate メソッドによって、渡された引数を使用する Bean フィールドを初期化する必要があります。

public void ejbCreate(int accountId)
        throws CreateException, RemoteException {
  _id = accountId;
  _value = 0; 
}

ejipt.createSQL env-entry には通常、次のようにデータベースに行を追加する INSERT ステートメントが含まれています。

<env-entry>
  <env-entry-name>ejipt.createSQL</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>INSERT INTO account (id, value) VALUES (?, ?)</
env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.createSQL.source</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>source1</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.createSQL.params</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>_id, _value</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.createSQL.paramTypes</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>INTEGER, INTEGER</env-entry-value>
</env-entry>

ejbLoad

Bean メソッドを実行する前に、コンテナでは、loadSQL ステートメントを実行し、指定されたフィールドにその結果をコピーして、データベースのステートと Bean インスタンスを同期化します。次に、データベースから取得された値に基づいて詳細に初期化を実行できるように、Bean で ejbLoad メソッドを呼び出します。


メモ

env-entry 要素または Bean プロパティで ejipt.isDataSharedfalse に設定した 場合は、最初の ejbLoad または ejbCreate を使用してインスタンスがすでにロード されていると、コンテナでは ejbLoad を呼び出しません。ejipt.isDataCachedtrue に設定した場合は、ロールバックの後のビジネス メソッドの前に ejbLoad を呼び 出しません。また、アクティブ化の後のビジネス メソッドの前にも ejbLoad を呼び 出しません。既定では、ロールバックまたはアクティブ化の後に再ロードします。


ejipt.loadSQL の値には通常、次のように、Bean インスタンスのデータが格納されている結果セットを返す SELECT ステートメントが含まれています。

<env-entry>
  <env-entry-name>ejipt.loadSQL</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>SELECT value FROM account WHERE id = ?</
env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.loadSQL.source</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>source1</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.loadSQL.params</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>_id</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.loadSQL.paramTypes</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>INTEGER</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.loadSQL.fields</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>_value</env-entry-value>
</env-entry>

ejbStore

Bean メソッドの終了後に、コンテナでは Bean インスタンスで ejbStore メソッドを呼び出します。この手順を使用すると、データベースにデータを格納して Bean インスタンスのステートを同期化する前に、Bean によってインスタンスのパラメータ フィールドを準備できます。

JRun では次のようにメソッドとプロパティを追加して、ejbStore の呼び出しを制御します。

ejipt.storeSQL の値には通常、次のように、データベースと Bean の現在のステートを同期化する UPDATE ステートメントが含まれています。

<env-entry>
  <env-entry-name>ejipt.storeSQL</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>UPDATE account SET value = ?WHERE id = 
?</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.storeSQL.source</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>source1</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.storeSQL.params</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>_value, _id</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.storeSQL.paramTypes</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>INTEGER, INTEGER</env-entry-value>
</env-entry>

dirty フラグが設定されていない場合、コンテナでは、表面的な比較によってインスタンスを保存するかどうかを判断します。コンテナは == 演算子を使用してフィールドのステートとキャッシュされているステートを繰り返し比較して、ステートが変化したかどうかを判断します。深いレベルでの変化が起きた場合、Bean メソッド内で dirty フラグを明示的に true に設定して、保存を強制しなければなりません。

ejbRemove

インスタンスを削除する場合、コンテナでは、インスタンスがデータベースから削除される前に必要なクリーンアップを実行できるように ejbRemove メソッドを呼び出します。ejbRemove では、SQL ステートメントで使用するパラメータを設定する必要があります。

ejipt.removeSQL の値には通常、次のように DELETE ステートメントが含まれています。

<env-entry>
  <env-entry-name>ejipt.removeSQL</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>DELETE FROM account WHERE id = ?</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.removeSQL.source</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>source1</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.removeSQL.params</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>_id</env-entry-value>
</env-entry>
<env-entry>
  <env-entry-name>ejipt.removeSQL.paramTypes</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>INTEGER</env-entry-value>
</env-entry>

finder メソッド

ほとんどのクライアント アプリケーションでは、1 つまたは複数の行を取得し、場合によっては更新することによってデータベースと対話します。行を作成することはほとんどありません。エンティティ Bean には、クライアントが 1 行以上の既存のデータにアクセスできる finder メソッドが実装されています。エンティティ Bean のホーム インターフェイスとその Bean 実装で、finder メソッドをコーディングします。

ejbFindByPrimaryKey

すべてのエンティティ Bean には、findByPrimaryKeyejbFindByPrimaryKey メソッドのペアが必要です。ただし、CMP を使用するエンティティ Bean の Bean 実装で、ejbFindByPrimaryKey を実装する必要はありません。ホーム インターフェイスの findByPrimaryKey を定義し、公開記述子の findByPrimaryKeySQL env-entry を指定する必要があります。

エンティティ Bean には、プライマリ キー クラス内のメンバのインスタンス変数がすべて含まれている必要があります。プライマリ キー フィールドのほかに、Bean では返される行の追加の列が含まれるインスタンス変数も定義できます。

ejbFindByPrimaryKey メソッドを呼び出した後、コンテナでは、
findByPrimaryKeySQL
env-entry によって指定された SQL ステートメントを実行します。最初に、パラメータ引数、またはプロパティで指定されているフィールド、あるいはその両方を SQL ステートメントの各パラメータにマッピングします。ストアド プロシージャを指定した場合は、キーとして渡された値に関連するオブジェクトがデータベースに含まれているかどうかを調べるチェックがストアド プロシージャに含まれている必要があります。データベース内にデータがある場合は、指定されているフィールドに格納した後で、該当する行を 1 つ返す必要があります。この行によって、コンテナでは、プライマリ キー クラスの有効なインスタンスを構築できます。プライマリ キーに渡されたメンバがデータベース内のオブジェクトに関連付けられていない場合、SQL は行を返しません。

コンテナでは、新しく作成されたプライマリ キー インスタンスを取り出し、そのインスタンスのオブジェクト テーブルから適切な EJB オブジェクトを検索します。オブジェクトが見つかった場合、そのオブジェクトをホーム インターフェイスの
findByPrimaryKey メソッドの結果として返します。EJB オブジェクトが見つからなかった場合、このメソッドでは finder 例外が返されます。

複数行 finder メソッド

CMP の使用時も複数行 finder メソッドを実装できます。finder メソッドごとに、find*SQL プロパティを指定する必要があります。たとえば、ホーム インターフェイスで定義された findBigAccounts メソッドがあるとします。

クライアントによってリモート インターフェイスの findBigAccounts メソッドが呼び出されると、finderSQL ステートメントと併用する Bean インスタンス内のパラメータを設定するために、コンテナでは、最初に Bean の ejbfindBigAccounts メソッドを呼び出します。finder メソッドではヌルを返す必要があります。次に、コンテナでは各 finder SQL ステートメントを順番に呼び出します。結果セットが返されるたびに、コンテナでは次の処理が実行されます。

  1. Bean インスタンス内のフィールドを設定します。
  2. 新しいプライマリ キーを作成します。
  3. 対応するフィールドをインスタンスからプライマリ キーにコピーします。
  4. そのプライマリ キーを、返されるプライマリ キーの一覧に追加します。

SQL プロパティは次のようになります。

ejipt.findBigAccountsSQL = SELECT id FROM sometable WHERE balance >
1000000
ejipt.findBigAccountsSQL.fields=custId

finder メソッドで基準が設定されている大口預金口座を見つけるために、次の
env-entry を使用します。

ejipt.findBigAccountsSQL = SELECT id FROM sometable WHERE balance >?
ejipt.findBigAccountsSQL.params=criteria
ejipt.findBigAccountsSQL.paramTypes=double
ejipt.findBigAccountsSQL.fields=custId

プロパティ ファイルでは、プライマリ キーにも含まれている Bean のフィールドに対する結果列からのマッピングを指定する必要があります。結果に基づいてプライマリ キーのコレクションが作成されると、EJB エンジンでは、関連するエンティティ オブジェクト、つまり公開時にリモート インターフェイスから生成された実装クラスのインスタンスの検索や作成に取りかかります。

finder が一覧または Java 2 コレクションのどちらを返すかによって、EJB エンジンでは、エンティティ オブジェクトの一覧から抜き出した EnumerationCollection のいずれかを作成し、それを呼び出し側に返します。