ヘッダーをスキップ
Oracle Containers for J2EE Orion CMP開発者ガイド
10g(10.1.3.1.0)
B31855-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

1 コンテナ管理の永続性を持つエンティティBeanの理解

この章ではエンティティBeanの一般的な概念と、特にコンテナ管理の永続性を持つエンティティBeanについて説明します。

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

エンティティBeanとは

J2EE SDK環境内において、エンティティBeanはリレーショナル・データベースのビジネス・オブジェクトを表します。通常、エンティティBeanはリレーショナル・データベースに基底の表を持ち、Beanの各インスタンスはそのデータベース内の行に対応します。

エンティティBeanには次のような特徴があります。

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

この項では、コンテナ管理の永続性を持つエンティティBeanに関する次のトピックについて説明します。

コンテナ管理の永続性を持つエンティティBean

用語的には、コンテナ管理の永続性とはエンティティBeanに必要なデータベース・アクセスを処理するEJBコンテナのプロセスのことです。つまり、BeanのコードにはSQLコールは含まれません。これによって、Beanのコードが基底データベースで不可視になります。Beanのデータの永続性を管理するためのいくつかのコールバック・メソッド(「コールバック・メソッド」を参照)は実装の必要がありません。これは、コンテナによってデータベースに対する永続データの格納およびリロードが行われるためです。また、コンテナではBeanに対する主キーも提供されるため、主キーの管理を用意する必要はありません(「主キーの構成」を参照)。

コンテナ管理の永続性を持つOrionエンティティBeanでは、エンティティBeanからデータベースへのデータを永続させるため、EJBコンテナでOrion永続性マネージャが使用されます。用語の詳細は「はじめに」を参照してください。

永続性マネージャの詳細は次のトピックを参照してください。

エンティティBeanのデプロイメント・ディスクリプタには、Beanの永続フィールド(「コンテナ管理の永続フィールド」を参照)および関連(「コンテナ管理の関連」を参照)を定義する抽象スキーマが含まれます。


注意:

抽象スキーマと物理スキーマという用語を混同しないでください。リレーショナル・データベースでは、物理スキーマは表および列で構成されますが、抽象スキーマは、データ・アクセス・コールの生成にコンテナで必要とされる情報のプロバイダとなります。

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

コンテナ管理の永続フィールド

エンティティBeanの永続フィールドはBeanの状態を定義します。これらのフィールドは基底となるデータベースに格納されます。コンテナは実行時に、Beanの状態とデータベースとの自動同期を実行します。デプロイ時に、コンテナは通常、表の列にマップされた永続フィールドでエンティティBeanをデータベース表にマップします。

永続フィールドはコンテナ管理の永続性では仮想的です。つまり、ユーザーはこのフィールドを抽象スキーマで宣言しますが、エンティティBeanクラスのインスタンス変数とはしません。ただし、ユーザーは永続フィールドに対するgetterおよびsetterをコードで次のように提供します。

public abstract String getEmployeeName() throws RemoteException

public abstract String getAddress() throws RemoteException

public abstract void setAddress(String newAddress) throws RemoteException

コンテナはこれらのメソッドの実装を提供します。

前述した例では、対応する永続フィールドはemployeeNameaddressです。

ejb-jar.xmlファイル形式のEJBデプロイメント・ディスクリプタが、これらのフィールドを永続的であると宣言します。各フィールド名は、デプロイメント・ディスクリプタの<cmp-field><field-name>要素で次のように定義する必要があります。

<entity>
    ...
    <cmp-field><field-name>employeeName</cmp-field></field-name>
    <cmp-field><field-name>address</cmp-field></field-name>
    ...
</entity>

永続フィールドの構成の詳細は、「コンテナ管理の永続フィールドの構成」を参照してください。

エンティティBeanの実装の詳細は、「コンテナ管理の永続性を持つEJB 2.0エンティティBeanの実装」を参照してください。

コンテナ管理の関連

エンティティBeanは他のエンティティBeanと関連する場合があります。このエンティティBeanの動作は、リレーショナル・データベースの表の動作と似ています。

EJBコンテナは、コンテナ管理の永続性を持つエンティティBeanにおける関連を制御します。

OC4Jは次のようなコンテナ管理の関連(CMR)タイプをサポートしています。

  • 1対1: エンティティBeanのインスタンスが他のエンティティBeanのインスタンスと関連します。たとえば、それぞれの車に1人の運転手が乗っているレーシング・トラックの仮想モデルでは、CarEJBDriverEJBが1対1関連にあります。

  • 1対多: エンティティBeanのインスタンスが他のエンティティBeanの複数のインスタンスと関連します。前述したレーシング・トラックの例を再び利用すると、レーシング・トラックで複数の車が競争できる場合に、RacingTrackEJBCarEJBに対して1対多関連にあります。

  • 多対1: エンティティBeanの複数のインスタンスが他のエンティティBeanの1つのインスタンスと関連します。たとえば、1対多のレーシング・トラックの例を逆の視点から見ると、多数の車が1つのレーシング・トラックで競争しているため、CarEJBRacingTrackEJBに対して多対1関連にあります。

  • 多対多: エンティティBeanのインスタンスが互いに複数のインスタンスと関連します。たとえば、レーシング・トラックではそれぞれの車が複数の整備士によって整備され、すべての整備士は複数の車を整備します。このことからCarEJBMechanicEJBは多対多関連にあります。

エンティティBeanはローカルBeanオブジェクトによって関連の「1」側を表しますが、「多」側はJavaのCollectionを使用して表されます。

これらのエンティティBean関連の参照整合性を維持するのは、EJBコンテナです。

詳細は次のトピックを参照してください。

CMRの方向

CMRの方向概念では、関連は双方向または単方向のどちらかになります。双方向の関連では、各エンティティBeanが他のBeanを参照する関連フィールドを持ちます。関連フィールド(「関連フィールド」を参照)を介して、エンティティBeanのコードはその関連オブジェクトにアクセスできます。単方向の関連では、1つのエンティティBeanのみが他のBeanを参照する関連フィールドを持ちます。

EJB QL問合せ(「EJB QLの理解」を参照)は関連全体をナビゲートできます。関連の方向によって、問合せがあるBeanから別のBeanにナビゲートできるかどうかが決まります。

関連フィールド

関連フィールドは関連するBeanを特定します。関連フィールドはデータベース表における外部キーと同様に機能します。

永続フィールド(「コンテナ管理の永続フィールド」を参照)と同様に、関連フィールドは仮想的であり、アクセス・メソッドを持つエンタープライズBeanクラスで定義されます。ただし、永続フィールドとは逆に、関連フィールドはBeanの状態は表しません。

関連フィールドの詳細は、「コンテナ管理の関連フィールドの構成」を参照してください。

コールバック・メソッド

コンテナ管理の永続性を持つエンティティBeanのライフ・サイクルを有効にするため、実装が必要なコールバック・メソッドが多数あります。これらのメソッドのいくつかはjavax.ejb.EntityBeanインタフェースで定義されますが、その他(ejbCreateejbPostCreate)の実装はEJB 2.0仕様で義務付けられています。

コンテナは指定された時刻にコールバック・メソッドを起動します。これらのメソッドにはロジックを追加する場合としない場合があります。

次の表に各メソッドの詳細と、エンティティBeanクラスのコールバック・メソッドに対する実装要件を一覧表示します。

コールバック・メソッド 詳細と実装要件
setEntityContext このメソッドはBeanインスタンスをコンテキスト情報と関連付けます。コンテナはBean作成後にこのメソッドをコールします。エンタープライズBeanは、トランザクション管理で使用するためのインスタンス変数にコンテキスト・オブジェクトへの参照を格納できます。トランザクションを管理するBeanは、セッション・コンテキストを使用してトランザクション・コンテキストを取得できます。

ユーザーは、Beanの存続中に存在するリソースをこのメソッド内に割り当てることもできます。これらのリソースはunsetEntityContextメソッドで解放します。

unsetEntityContext このメソッドは関連付けられたエンティティ・コンテキストを設定解除し、setEntityContextメソッドで割り当てられたリソースを解放します。
ejbCreate エンティティBeanには1つ以上のejbCreateメソッドが含まれます。

通常、このメソッドは次の動作を実行します。

  • エンティティの状態をデータベースに挿入します。

  • インスタンス変数を初期化します。

  • 主キーを返します。

このメソッドを記述する際、次の条件に従う必要があります。

  • アクセス制御修飾子はpublicです。

  • 戻り型は主キーです。

  • 引数はJava RMI APIに対して有効な型です。

  • メソッド修飾子はfinalでもstaticでもありません。

ejbPostCreate エンティティBeanクラスの各ejbCreateメソッドに対してejbPostCreateメソッドを記述する必要があります。コンテナはejbCreateメソッドをコールした後すぐejbPostCreateメソッドを起動します。ほとんどの場合、ejbPostCreateメソッドは空のままにします。

このメソッドを記述する際、次の条件に従う必要があります。

  • 引数の数と型が対応するejbCreateメソッドに一致します。

  • アクセス制御修飾子はpublicです。

  • メソッド修飾子はfinalでもstaticでもありません。

  • 戻り型はvoidです。

ejbActivate このメソッドは、エンティティBeanインスタンスが準備状態にあるときに必要な追加リソースを取得する機会を提供します。

ユーザーは少なくとも、このコールバック・メソッドの空の実装を行う必要があります。

ejbPassivate このメソッドは、エンティティBeanインスタンスがプールされているときに保持する必要がないリソースを解放する機会を提供します(通常、これらのリソースはejbActivateメソッドの実行時に割り当てられています)。

ユーザーは少なくとも、このコールバック・メソッドの空の実装を行う必要があります。また、クリーンアップ機能を実行するためのロジックを追加する場合もあります。

ejbRemove このメソッドはエンティティの状態をデータベースから削除します。コンテナは、クライアントがエンティティBeanを(removeメソッドを起動して)削除した後にこのメソッドをコールします。

ユーザーは少なくとも、このコールバック・メソッドの空の実装を行う必要があります。また、クリーンアップ機能を実行するためのロジックを追加する場合もあります。

エンティティBeanはデータベース削除によって直接的に削除される可能性もあるので、注意してください。たとえば、SQLスクリプトがエンティティBeanの状態を含む行を削除する場合は、そのエンティティBeanも削除されます。

ejbLoad このメソッドはインスタンス変数をデータベースからリフレッシュします。

EJBコンテナが、エンティティBeanのインスタンス変数をデータベースに格納されている対応する値と同期化する必要がある場合、ejbLoadおよびejbStoreメソッドを起動します。

クライアントがejbLoadおよびejbStoreメソッドをコールしない場合もあるので注意してください。

このメソッド内に永続データをリストアするための機能は必要ありません。永続性マネージャはユーザーのすべての永続データをリストアします。ただし、ユーザーは少なくとも空の実装を行う必要があります。

ejbStore このメソッドは変数をデータベースに書き込みます。

EJBコンテナが、エンティティBeanのインスタンス変数をデータベースに格納されている対応する値と同期化する必要がある場合、ejbLoadおよびejbStoreメソッドを起動します。

クライアントがejbStoreメソッドをコールしない場合もあるので注意してください。

このメソッド内に永続データを保存するための機能は必要ありません。永続性マネージャはユーザーのすべての永続データをデータベースに保存します。ただし、ユーザーは少なくとも空の実装を行う必要があります。

ejbFindByPrimaryKey 名前が示すとおり、このメソッドは引数として主キーを受け入れて、その主キーをエンティティBeanの特定に使用します。

このメソッドを記述する際、次の条件に従う必要があります。

  • アクセス制御修飾子はpublicです。

  • メソッド修飾子はfinalでもstaticでもありません。

  • 戻り型は主キーまたは主キーの集合です。

コンテナに主キーを返すための機能は必要ありません。主キーがejbCreateメソッドで初期化された後、コンテナは主キーを管理します。ただし、ユーザーはこのメソッドの空の実装を行う必要があります。


エンティティBeanに対する問合せ

ユーザーは、エンティティBeanのfinderメソッド(「finderメソッドの理解」を参照)またはselectメソッド(「selectメソッドの理解」を参照)を使用して、エンティティBeanのインスタンスに対して問合せを行います。

選択基準は適切な問合せ構文を使用して表します(「問合せ構文の理解」を参照)。

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

EJB QLの理解

EJB問合せ言語(EJB QL)は、移植性があり最適化可能な形式によるfinderメソッドおよびselectメソッドのセマンティクスの定義に使用される仕様言語です。Orion永続性マネージャはEJB QLの自動コンパイルを実行できます。ユーザーは、エンティティBeanのデプロイメント・ディスクリプタでEJB QL問合せを定義します。

EJB QLを使用すると次のような利点があります。

  • データベース構造(表やフィールドなど)を知る必要がありません。

  • データベースの表およびフィールドを使用するかわりに、エンティティBeanの属性を使用して問合せを構成できます。

  • 問合せの関連を使用して、属性から属性へのナビゲーションを提供できます。

  • EJB QLの問合せは、データベースに依存していないため、移植性があります。

  • 参照クラスをSELECT句で指定できます。

EJB QLの問合せの難点は、複合問合せを構成する際に使用することが難しい点です。

EJB QLには次のような制限があります。

  • コメントは使用できません。

  • 日付および時間の値の単位はミリ秒で、Java longを使用します。日付または時間のリテラルは整数リテラルとする必要があります。ミリ秒の値を生成するには、java.util.Calendarクラスを使用します。

  • EJB 2.0のコンテナ管理の永続性では継承がサポートされていません。このため、型が異なる2つのエンティティBeanは比較できません。

問合せ構文の理解

ユーザーは、EJB QL(「EJB QLの理解」を参照)またはネイティブSQLを使用して、基底となるリレーショナル・データベースに対するエンティティBean問合せを表すことができます。

移植性があり最適化可能なEJB QLの方がより推奨されます。

EJB QL問合せにはSELECTFROMおよびWHEREという3つの句があります。SELECTおよびFROM句は必須ですが、WHERE句はオプションです。EJB QL問合せのハイレベル構文を次に示します。

EJB QL ::= select_clause from_clause [where_clause]

SELECT句は問合せで返されるオブジェクトまたは値の型を定義します。戻り型はローカル・インタフェース、リモート・インタフェースまたは永続フィールドのいずれかになります。

FROM句は、SELECTおよびWHERE句で参照される場合がある、1つ以上の識別変数を宣言することで問合せの有効範囲を定義します。識別変数は次の要素のいずれかを表します。

  • エンティティBeanの抽象スキーマ名

  • 1対多関連における「多」側である集合のメンバー

WHERE句は問合せで取得されるオブジェクトまたは値を制限する条件式です。オプションではありますが、ほとんどの問合せにはWHERE句があります。

EJB QL構文の詳細は、http://java.sun.com/products/ejb/docs.htmlでEJB 2.0仕様を参照してください。

EJB QL問合せ構文を次の例で示します。たとえば、エンティティBeanのホーム・インタフェースでfindByZipCodeメソッドを宣言して、特定のジップ・コードを持つEmployee Beanをすべて取得します。

public Collection findByZipCode(String zipCode) throws RemoteException, CreateException

これはデプロイメント・ディスクリプタの次のEJB QL文を使用して表されます。

FROM contactInfo WHERE contactInfo.zip = ?1

このEJB QL文は「zipCode引数に等しいジップ・コードを持つEmployee Beanをすべて選択」するという意味です。選択するものを示すSELECT句は、finderメソッドのEJB QL文では必要ありません。これは、finderメソッドがそのBeanタイプのリモート参照を常に選択するためです。

ネイティブSQLは、EJB QLがサポートしていない基底リレーショナル・データベースの詳細な問合せ機能を利用する場合に適しています。

EJB QLはfinderメソッド(「finderメソッドの理解」を参照)とselectメソッド(「selectメソッドの理解」を参照)で使用できます。ネイティブSQLを使用するには直接JDBCコールを使用する必要があります。

finderメソッドの理解

EJBファインダはEJB 2.0仕様で定義されている問合せです。EJBファインダはエンティティBean参照を取得します(および返します)が、問合せはJavaオブジェクトを返します。

ファインダには検索基準を定義するfinderメソッド(ejbFind)が含まれます。

findByPrimaryKey finderメソッドは常に両方のホーム・インタフェース(ローカルとリモート)で定義され、主キーを使用してこのBeanに対するエンティティ参照を取得します。一方または両方のホーム・インタフェースで他のfinderメソッドを定義して、1つまたは複数のエンティティBean参照を取得できます。


注意:

finderメソッドはクライアントに公開されます。

finderメソッドの定義および実装の詳細は、「EJB QLのfinderメソッドの実装」を参照してください。

selectメソッドの理解

selectメソッド(ejbSelect)は、主にコンテナ管理の永続フィールド(「コンテナ管理の永続フィールド」を参照)または関連フィールド(「関連フィールド」を参照)の値を返すために使用されます。すべての値は固有のオブジェクト型で返されます。プリミティブ型はすべて、同様の関数を持つオブジェクトでラッピングされます(たとえば、intプリミティブ型はIntegerオブジェクトでラッピングされます)。ejbSelectメソッドは、エンティティBeanインスタンス内の内部使用を目的にした問合せメソッドです。抽象Beanで指定されるため、ejbSelectメソッドはホームまたはコンポーネント・インタフェースでクライアントに直接公開されません。抽象的に定義することで、それぞれのBeanにこのようなメソッドをゼロ以上含むことができます。

selectメソッドには次のような特徴があります。

  • メソッド名にはejbSelectという接頭辞が必要です。

  • publicとして宣言する必要があります。

  • abstractとして宣言する必要があります。

  • アプリケーション固有の例外を同様に指定する場合でも、throws句でjavax.ejb.FinderExceptionを指定する必要があります。

  • EJB 2.0では、ejb-jar.xmlファイルのresult-type-mappingタグによってejbSelectメソッドの戻り型が決まります。EJBObjectを返すにはフラグをRemoteに設定し、EJBLocalObjectを返すにはフラグをLocalに設定します。

selectメソッドの詳細は、「EJB QLのselectメソッドの実装」を参照してください。

データベース・リソースの競合の回避

エンティティBeanの並行性とデータベース分離レベルを使用することで、リソース競合を回避し、同時実行中に各ユーザーがデータベースへの変更をお互いに上書きすることを防止します。

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

エンティティBeanのデータベース分離レベルとリソース競合

java.sql.Connectionオブジェクトは特定のデータベースへの接続を表します。Connectionではリソース競合からの保護を定義する4つのデータベース分離レベルが提供されます。2人以上のユーザーが同じリソースを更新しようとすると、更新の紛失が起こる場合があります。つまり、1人のユーザーが、認識しないまま他のユーザーのデータを上書きする可能性があります。

Oracleでは次の分離レベルがサポートされています。

  • transaction_read_committed: 不正な読取りが防止されます。反復不可読取りと仮読取りが発生する場合があります。このレベルは、コミットされていない変更を持つ行をトランザクションが読み取ることのみを阻止します。

  • transaction_serializable: 不正な読取り、反復不可読取りおよび仮読取りが防止されます。このレベルにはtransaction_repeatable_readにおける禁止が含まれます。さらに、あるトランザクションがWHERE条件を満たすすべての行を読み取り、2番目のトランザクションがWHERE条件を満たす行を挿入し、最初のトランザクションが同じ条件について再読取りを行い、2回目の読取りで追加的な「ファントム」行を取得する、という仮想状況の発生も阻止されます。

データベース分離レベルの詳細は、「データベース分離レベルの構成」を参照してください。

エンティティBeanの並行性モードとリソース競合

OC4Jには、コンテナ管理の永続性を持つエンティティBean内のリソース競合とパラレル実行を処理するための並行性モードも用意されています。並行性モードでは、リソース競合管理のためいつ遮断するか、またはいつパラレル実行を行うかを決定します。

使用できる並行性モードの一覧を次に示します。

  • pessimistic: リソース競合を管理し、パラレル実行を許可しません。1人のユーザーのみが指定された時間にエンティティBeanを実行できます。

  • optimistic: リソース競合を監視しません。このため、データベース分離レベルで並行性を管理します。複数のユーザーがエンティティBeanをパラレルに実行できます。

  • read-only: コンテナはBeanの状態に対するあらゆる更新を許可しません。複数のユーザーがエンティティBeanをパラレルに実行できます。

並行性モードの詳細は、「並行性モードの構成」を参照してください。

組合せがリソース競合の結果に影響する場合は、エンティティBeanの並行性モードとデータベース分離レベルの両方を指定することができます。詳細は「エンティティBeanのデータベース分離レベルと並行性モードの組合せ」を参照してください。

エンティティBeanのデータベース分離レベルと並行性モードの組合せ

データベース分離レベルの設定は、pessimisticおよびread-only並行性モードには影響しません。分離レベルは、外部ソースがデータベースを変更している場合にのみ関係します。

committedデータベース分離レベルでoptimistic並行性モードを選択した場合、更新が失われる可能性があります。serializable分離レベルでoptimistic並行性モードを選択した場合、更新が失われることはなく、データの整合性が常に保たれます。ただし、リソース競合エラーとしてORA-8177例外を受け取る場合があります。

pessimistic、optimisticおよびserializable設定の相違点

pessimistic並行性モードのエンティティBeanでは、複数のクライアントによる実行は(同じ主キーの同じインスタンスまたは異なるインスタンスのどちらでも)許可されません。1回に1つのクライアントのみがインスタンスを実行できます。

optimistic並行性モードのエンティティBeanでは、Beanの複数のインスタンスがパラレルに実行できます。これによって、2つの異なるトランザクションが同じ行を同時に更新する場合があるため、更新の紛失(および競合)が起こる可能性があります。

トランザクション分離レベルをserializableに設定すると、競合が発生した場合の検知が可能になります。現在、トランザクションの1つの更新でSQLExceptionが発生した場合、このトランザクションはロールバックされます。

オプションで、<entity-deployment>要素のtx-retries属性を1よりも大きい値に設定すると、トランザクションの再試行が行われます。<entity-deployment>要素およびその属性の詳細は、表A-1「<entity-deployment>要素の属性」を参照してください。

エンティティBeanの並行性モードとクラスタリング

すべての並行性モードは、独立環境またはクラスタリング環境のどちらで使用される場合でも同じように動作します。これは、並行性モードがデータベース・レベルでロックされているためです。このため、pessimistic Beanインスタンスがノード間でクラスタリングされている場合でも、1つのインスタンスが実行を試行すると、データベースはその他すべてのインスタンスをロックします。

詳細は次のトピックを参照してください。

  • 『Oracle Containers for J2EE構成および管理ガイド』の「クラスタリングの概要」

  • 『Oracle Containers for J2EE構成および管理ガイド』の「OC4Jでのアプリケーションのクラスタリング」

  • 『Oracle Application Server高可用性ガイド』のアクティブ/アクティブ・トポロジにおけるOracle Application Server Cluster(OC4J)に関する項

コンテナ管理の永続性を持つエンティティBeanを使用する場合

次のような状況の場合に、コンテナ管理の永続性を持つエンティティBeanを使用することをお薦めします。


注意:

Oracle移行ツールを使用してアプリケーションをTopLink永続性マネージャに移行することをお薦めします。詳細は「TopLink永続性マネージャへの移行」を参照してください。