www.bea.com code library downloads support.bea.com BEA logo

WebLogic エンタープライズ JavaBeans プログラマーズ ガイド

 Previous Next Contents Index View as PDF

コンテナ管理による永続性サービス : 高度な機能

以下の節では、WebLogic Server EJB コンテナで利用できるコンテナ管理による永続性 (CMP) サービスの高度な機能を説明します。「高度」な機能とは、パフォーマンス関連または特殊な用途向けの機能を指します。基本的な CMP 機能については、「コンテナ管理による永続性サービス : 基本機能」を参照してください。

パフォーマンスに関する機能 :

特殊な用途向けの機能 :

 


読み込み専用マルチキャストの無効化

読み込み専用マルチキャストを無効化すると、キャッシュされたデータを効率的に無効にできます。

read-only エンティティ Bean を無効にするには、CachingHome または CachingLocalHome インタフェースの次の invalidate() メソッドを呼び出します。

図6-1 CachingHome インタフェースと CachingLocalHome インタフェースを示すコード例

package weblogic.ejb;
public interface CachingHome {
	public void invalidate(Object pk) throws RemoteException;
public void invalidate (Collection pks) throws RemoteException;
public void invalidateAll() throws RemoteException;
public interface CachingLocalHome {
	public void invalidate(Object pk) throws RemoteException;
public void invalidate (Collection pks) throws RemoteException;
public void invalidateAll() throws RemoteException
}

次のコード例は、ホームを CachingHome にキャストしてからメソッドを呼び出す方法を示したものです。

図6-2 ホームをキャストしてからメソッドを呼び出す方法を示すコード例

import javax.naming.InitialContext; 
import weblogic.ejb.CachingHome;
Context initial = new InitialContext(); 
Object o = initial.lookup("CustomerEJB_CustomerHome");
CustomerHome customerHome = (CustomerHome)o;
CachingHome customerCaching = (CachingHome)customerHome; 
customerCaching.invalidateAll();

invalidate() メソッドを呼び出すと、read-only エンティティ Bean はローカル サーバで無効化され、マルチキャスト メッセージがクラスタ内の他のサーバに送信されてキャッシュされているその Bean のコピーが無効化されます。無効化された読み込み専用エンティティ Bean を次に呼び出すと、ejbLoad が呼び出されます。 ejbLoad() は、最新の永続的データを基盤となるデータストアから読み出します。

WebLogic Server は、トランザクションの更新が完了してから invalidate() メソッドを呼び出します。トランザクションの更新中に無効化処理が行われた場合、アイソレーション レベルでコミットされていないデータの読み出しが許可されていないと、更新前のデータが読み出される可能性があります。

 


read-mostly パターン

WebLogic Server は、weblogic-ejb-jar.xml に設定される read-mostly キャッシュ方式をサポートしていません。しかし、頻繁に更新されない EJB データがある場合、read-only EJB と read-write EJB を組み合わせることによって、「read-mostly パターン」を作成できます。

WebLogic Server は、read-mostly パターンの自動 invalidate() メソッドを提供します。このパターンでは、読み込み専用エンティティ Bean と読み書き対応エンティティ Bean が同じデータにマップされます。データを読み出すには読み込み専用エンティティ Bean を使用し、データを更新するには読み書き対応エンティティ Bean を使用します。

read-mostly パターンでは、read-only エンティティ EJB は、weblogic-ejb-jar.xml ファイルの read-timeout-seconds デプロイメント記述子要素によって指定されている間隔で Bean データを取得します。別の read-write エンティティ EJB は、その read-only EJB と同じデータをモデル化し、必要な間隔でそのデータを更新します。

read-mostly パターンを作成する場合、以下の注意に従って、データの一貫性に関する問題が発生しないようにしてください。

WebLogic Server クラスタでは、read-only EJB のクライアントは、キャッシュされた EJB データを使用することで恩恵を受けることができます。read-write EJB のクライアントは、真のトランザクション動作から恩恵を受けることができます。これは、read-write EJB の状態が常に基盤データベース上のそのデータの状態と一致するからです。詳細については、「クラスタ内のエンティティ EJB」を参照してください。

 


エンティティ Bean のリレーションシップ キャッシング

リレーションシップ キャッシングでは、関係する複数 Bean をキャッシュにロードし、それらに結合クエリを発行してクエリの発行回数を削減することによって、エンティティ Bean のパフォーマンスが高められます。次の例を検討してください。

アプリケーションに、次のような関係を持つエンティティ Bean が含まれているとします。

customerBean

1 対多関係を持つ

accountBean

accountBean

1 対 1 関係を持つ

addressBean

customerBean

1 対 1 関係を持つ

phoneBean


 

accountBean および addressBean の EJB コード (1 対 1 の関係を持つ) を検討します。

Account acct = acctHome.findByPrimaryKey("103243"); 
Address addr = acct.getAddress();

リレーションシップ キャッシングが行われなければ、コードの 1 行目で accountBean をロードする SQL クエリが発行され、2 行目で addressBean をロードする SQL クエリが発行されます。これにより、データベースには 2 つのクエリが生じます。

リレーションシップ キャッシングが行われると、AccountEJB と AddressEJB の双方をロードする 1 つのクエリがコードの 1 行目で発行されるため、パフォーマンスは向上するはずです。したがって、ある特定のファインダ メソッドの実行後に関連の Bean へのアクセスがあることが分かっている場合は、リレーションシップ キャッシング機能によってそれをファインダ メソッドに知らせることをお勧めします。

リレーションシップ キャッシングの指定

リレーションシップ キャッシングを指定するには、その Bean の weblogic-cmp-rdbms-jar.xml ファイルの relationship-caching デプロイメント記述子を設定します。

次の XML コード例によって、リレーションシップ キャッシングを指定する方法が分かります。

<relationship-caching>
<caching-name>cacheMoreBeans</caching-name>
<caching-element>
<cmr-field>accounts<</cmr-field>
<group-name>acct_group</group-name>
<caching-element>
<cmr-field>address</cmr-field>
<group-name>addr_group</group-name>
</caching-element>
</caching-element>
	<caching-element>
<cmr-field>phone</cmr-field>
<group-name>phone_group</group-name>
</caching-element>
</relationship-caching>

accounts フィールドと phone フィールドは、customerBean テーブル上のコンテナ管理による関係 (CMR) フィールドです。また、address フィールドは accountBean テーブル上の cmr フィールドです。addr_group および phone_group は、addressBean および phoneBean 内のグループです。

caching-element デプロイメント記述子をネストすることにより、関係する Bean を複数レベルでロードできるようになります。上記の XML コード例では、addressBeanaccountBean 内でネストになっているので、第 2 レベルの関連 Bean にあたります。現在、指定できる caching-element の数に制限はありません。しかし、caching-element のレベルをあまり多く設定しすぎると、そのトランザクションのパフォーマンスに影響すると考えられます。

リレーションシップ キャッシングの有効化

リレーションシップ キャッシングを有効化するには、次の手順に従います。

  1. weblogic-cmp-rdbms-jar.xml ファイルの weblogic-query 要素で caching-name デプロイメント記述子要素を指定します。

    caching-name 要素が weblogic-query XML 要素内で指定されている場合、ファインダ クエリが実行されると、WebLogic Server は、関係付けられている accountBeanphoneBean とともに、その account の addressBean をキャッシュにロードします。

  2. weblogic-ejb-jar.xml ファイル上で 、ある関係が指定されている Bean (たとえば、上記の XML コード例では customerBean) の finder-load-bean 要素が False に設定されていないことを確かめます。このようにしなければ、リレーションシップ キャッシングが有効になりません。finder-load-bean 要素のデフォルトは True です。
  3. その Bean の weblogic-cmp-rdbms-jar.xml ファイルの database-type デプロイメント記述子を指定します。リレーションシップ キャッシングでは外部結合のクエリを使用しますが、外部結合にはすべてのデータベースにとって標準的な構文がないためです。

リレーションシップ キャッシングでは結合クエリを使用し、結合クエリではおそらく結果を ResultSet 内のテーブルに複写するため、relationship-caching 要素で指定した caching-element デプロイメント記述子の数が ResultSet に複写される結果の数に直に影響してきます。1 対多関係では、relationship-caching 要素であまり多くの caching-element デプロイメント記述子を指定しないでください。caching-element デプロイメント記述子の数に対して複写される結果の数が乗算される可能性があります。

caching-element デプロイメント記述子要素は weblogic-cmp-rdbms-jar.xml ファイルで指定します。

リレーションシップ キャッシングの制限

リレーションシップ キャッシングの機能には次のような制限があります。

  1. リレーションシップ キャッシングは 1 対 1 または 1 対多関係に対してのみ働きます。
  2. weblogic-ql を使用した場合、この機能は、EJBObject Bean または EJBLocalObject Bean への参照を返すファインダ メソッドを使ったときのみ機能します。
  3. ファインダ メソッドまたは選択メソッドでリレーションシップ キャッシングを有効にする場合、クエリの結果は、たとえ distinct キーワードを指定していなくても常に異なる集合になります。ResultSet に複写されているものが元のデータの結果なのか、外部結合の結果なのか見分けることができないからです。

 


エンティティ Bean の組み合わせキャッシング

組み合わせキャッシングを使用すると、同じ J2EE アプリケーション内の複数エンティティ Bean 間で 1 つの実行時キャッシュを共有できます。これまでは、アプリケーションの一部であるエンティティ Bean それぞれに対し、別々のキャッシュをコンフィグレーションする必要がありました。このことは、エンティティ Bean ごとにキャッシュをコンフィグレーションするのに時間がかかる、アプリケーションの実行により多くのメモリが必要になるなど、利便性やパフォーマンスの点で若干の問題を招いていました。この機能は、それらの問題解決に役立ちます。

アプリケーションレベルのキャッシュをコンフィグレーションするには、次の手順に従います。

  1. weblogic-application.xml ファイルが EAR ファイルのMETA-INF ディレクトリ内にあるか確めます。
  2. weblogic-application.xml ファイルに次のように入力します。
    <weblogic-application>
    <ejb>
    <entity-cache>
    <entity-cache-name>large_account</entity-cache-name>
    <max-cache-size>
    <megabytes>1</megabytes>
    </max-cache-size>
    </entity-cache>
    </ejb>
    </weblogic_application>

    entity-cache 要素を使用して、実行時にエンティティ Bean インスタンスをキャッシュする、名前付きのアプリケーションレベル キャッシュを定義します。各キャッシュを何個のエンティティ Bean が参照するかについて制限はありません。

    entity-cache のサブ要素は、 weblogic-ejb-jar.xml デプロイメント記述子ファイルで使われるのと同じ基本的意味を持っています。

  3. weblogic-ejb-jar.xml ファイルの entity-descriptor 要素を指定します。

    entity-descriptor 要素を使用し、エンティティ Bean がアプリケーションレベルのキャッシュを使用するようにコンフィグレーションします。

weblogic-application.xml デプロイメント記述子については、『WebLogic Server アプリケーションの開発』の「application.xml デプロイメント記述子の要素」に詳細な説明があります。

 


トランザクション間のキャッシング

トランザクション間のキャッシング、または、長期キャッシングを使用すると、EJB コンテナはエンティティ Bean の永続データをトランザクション間でキャッシュできるようになります。エンティティ Bean の同時方式が ExclusiveReadOnlyOptimistic のいずれかに設定されている場合に、トランザクション間のキャッシングを実行できます。エンティティ Bean の同時方式を設定する手順については、「同時方式の指定」を参照してください。

Exclusive 同時方式でのトランザクション間のキャッシング

Exclusive 同時方式のエンティティ Bean で長期キャッシングを有効にする場合、EJB コンテナは基盤データへの更新アクセスを排他的にする必要があります。これはつまり、その EJB コンテナ以外の別のアプリケーションがデータを更新してはならないということです。あるクラスタ内に Exclusive 同時方式の EJB をデプロイする場合、長期キャッシングは自動的に無効になります。クラスタ内のどのノードからもデータを更新できるからです。これにより長期キャッシングは実行不能になります。

WebLogic Server の旧バージョンでは、この機能は weblogic-ejb-jar.xml の db-is-shared 要素によって制御されていました。

注意: Exclusive 同時方式は単一サーバでの機能です。クラスタ化されたサーバでは使用しないでください。

ReadOnly 同時方式でのトランザクション間のキャッシング

ReadOnly 同時方式のエンティティ Bean で長期キャッシングを無効にした場合、EJB コンテナでは読み込み専用データの長期キャッシングを常に実行するので、caching-between-transactions の設定値は無視されます。

Optimistic 同時方式でのトランザクション間のキャッシング

Optimistic 同時方式のエンティティ Bean で長期キャッシングを有効にした場合、EJB コンテナは前回のトランザクションでキャッシュされた値を再利用します。コンテナは、トランザクションの最後にオプティミスティックに競合をチェックすることによって、更新におけるトランザクションの一貫性を保証します。オプティミスティックなチェックを設定する手順については、「Optimistic 同時方式」を参照してください。

また、オプティミスティックな競合を回避できるように、オプティミスティックなデータ更新に関する通知が他のクラスタ メンバーにプロ―ドキャストされます。

トランザクション間のキャッシングの有効化

トランザクション間のキャッシングを有効にするには、次の手順に従います。

  1. 次のオプションの 1 つを選択し、weblogic-ejb-jar.xml ファイルの caching-between-transactions 要素を設定します。

トランザクション間のキャッシュを使用した ejbStore() の呼び出しの制限

デフォルトによって、WebLogic Server は各トランザクションの開始時に ejbLoad() を呼び出します。この動作は、複数のソースがデータベースを更新するような環境に適しています。複数のクライアント (WebLogic Server を含む) が EJB の基盤データを変更する可能性があるため、ejbLoad() の最初の呼び出しは、キャッシュ済みデータを更新する必要があることを Bean に通知し、確実に最新のデータが処理対象になるようにします。

単一の WebLogic Server トランザクションのみが特定の EJB にアクセスするような特殊な環境では、ejbLoad() をデフォルトで呼び出す必要はありません。EJB の基盤データを更新するクライアントまたはシステムは他に存在しないので、WebLogic Server の EJB データのキャッシュは常に最新のものとなります。こうしたケースでは、ejbLoad() を呼び出しても、Bean にアクセスする WebLogic Server クライアントに対して余計なオーバーヘッドが発生するだけです。

単一の WebLogic Server トランザクションが特定の EJB にアクセスする場合、ejbLoad() の不要な呼び出しを避けるために、WebLogic Server には cache-between-transactions デプロイメント パラメータが用意されています。デフォルトでは、cache-between-transactions は各 EJB に対して Bean の weblogic-ejb-jar.xml ファイルで「false」に設定されています。このため、ejbLoad() は各トランザクションの開始時に必ず呼び出されます。単一の WebLogic Server トランザクションだけが EJB の基盤データにアクセスするようなケースでは、その Bean の weblogic-ejb-jar.xml ファイルの d を「true」に設定できます。cache-between-transactions を「true」に設定して EJB をデプロイすると、WebLogic Server の単一のインスタンスが以下の場合に限り、その Bean の ejbLoad() を呼び出します。

トランザクション間のキャッシングに関する制限と警告

cache-between-transactions を「true」に設定すると、EJB の基盤データが 1 つの WebLogic Server インスタンスによって更新されるか、複数のクライアントによって更新されるかにかかわらず、WebLogic Server のデフォルト ejbLoad() 動作 (コンテナ管理による永続性) がオーバーライドされます。間違って cache-between-transactions を「true」に設定し、複数のクライアント (データベース クライアント、別の WebLogic Server インスタンスなど) が Bean データを更新する場合、データの完全性が失われる恐れがあります。

エンティティ Bean の concurrency strategy を「Database」オプションに設定した場合は、cache-between-transactions を「true」に設定しないでください。Database 同時方式の場合、EJB コンテナではエンティティ Bean クラスのインスタンスをキャッシュすることになっているので、Weblogic Server はこの設定を無視します。その一方、コンテナはトランザクション間で EJB インスタンスの状態をキャッシュしません。その代わりとして、WebLogic Server ではトランザクションの開始時に各インスタンスに対し ejbLoad() を呼び出します。つまり、トランザクション開始時の ejbload() の呼び出しを妨ぐことに等しい、cache-between-transactions への「true」の設定は無効だということです。

また、Exclusive 同時方式の制限により、Exclusive 同時方式を使用する場合に WebLogic Server クラスタで cache-between-transactions を「true」に設定することはできません。Optimistic またはReadOnly同時方式では、この要素を設定することが可能です。

 


エンティティ EJB に対する ejbLoad() と ejbStore() の動作

WebLogic Server は、ejbLoad() および ejbStore() への呼び出しを使用して、エンティティ EJB の永続フィールドを読み書きします。デフォルトでは、WebLogic Server は ejbLoad()ejbStore() を次の手順で呼び出します。

  1. エンティティ EJB のトランザクションが開始されます。クライアントが明示的に新しいトランザクションを開始して Bean を呼び出すか、または WebLogic Server が Bean のメソッド トランザクション属性に従って新しいトランザクションを開始します。
  2. WebLogic Server は ejbLoad() を呼び出して、Bean の永続データの最新バージョンを基盤となるデータストアから読み出します。
  3. トランザクションがコミットすると、WebLogic Server は ejbStore() を呼び出して、永続フィールドを基盤となるデータベースに書き込みます。

こうした ejbLoad()ejbStore() の呼び出しという単純なプロセスにより、新しいトランザクションは常に EJB の最新の永続的データを使用し、コミット時には常にそのデータをデータベースに書き込むようになります。しかし、環境によっては、パフォーマンス上の理由から ejbLoad()ejbStore() の呼び出しを制限することができます。この場合、代わりに ejbStore() の呼び出しをより頻繁に行って、コミットされていないトランザクションの中間結果を参照することができます。

WebLogic Server には、ejbLoad()ejbStore() の動作をコンフィグレーションするためのデプロイメント記述子要素が weblogic-ejb-jar.xml および weblogic-cmp-rdbms-jar.xml ファイルに用意されています。以降の節では、これらの要素について説明します。

is-modified-method-name に関する警告

is-modified-method-name 要素を使用すると、ejbStore() の不必要な呼び出しを避けることによってパフォーマンスを高めることができます。しかし、いつ更新が行われたかを正確に識別することは、EJB 開発者にとっては負担が大きい作業です。指定された is-modified-method-name が不正確なフラグを WebLogic Server に返した場合、データの完全性に関する問題が起こりかねず、多くの場合、こうした問題を追跡するのは困難です。

エンティティ EJB の更新内容がシステム内で失われたと思われる場合、まずどのような状況でもすべての is-modified-method-name 要素の値が「true」を返すように設定してください。これにより、WebLogic Server のデフォルト ejbStore() 動作に戻すことができ、問題が解決する場合があります。

delay-updates-until-end-of-tx を使用した ejbStore() 動作の変更

デフォルトでは、WebLogic Server はトランザクションのすべての Bean の永続ストレージをトランザクションの完了 (コミット) 時にだけ格納します。これにより、不必要な更新と ejbStore() の呼び出しの反復が回避され、一般にパフォーマンスが向上します。

データベースがアイソレーション レベルの READ_UNCOMMITTED を使用する場合、他のデータベース ユーザが継続中のトランザクションの中間結果を参照できるようにすることができます。こうしたケースでは、トランザクションの完了時にだけデータストアを更新するという WebLogic Server のデフォルト動作は不適切な場合があります。

デフォルト動作を無効にするには、delay-updates-until-end-of-tx デプロイメント記述子要素を使用します。この要素は、weblogic-ejb-jar.xml ファイルで設定します。この要素を「false」に設定すると、WebLogic Server はトランザクションの完了時ではなく各メソッド呼び出しの後に ejbStore() を呼び出します。

delay-updates-until-end-of-tx を false に設定しても、各メソッド呼び出しの後にデータベース更新が「コミットされた」状態になるわけではありません。更新はデータベースに送信されるだけです。更新は、トランザクションの完了時にのみデータベースにコミットまたはロールバックされます。

 


グループ

コンテナ管理による永続性では、グループを使用して、エンティティ Bean の特定の永続的な属性を指定します。field-group は、Bean のコンテナ管理による永続性 (cmp) フィールドとコンテナ管理による関係 (cmr) フィールドのサブセットを表します。Bean 内の関連フィールドを、障害のあったグループにまとめて 1 つのユニットとしてメモリ内に入れることができます。グループをクエリまたは関係に関連付けることができます。それによって、クエリを実行するか、または関係に従った結果として Bean がロードされたときに、グループ内の指定フィールドのみがロードされます。

指定したグループを持たないクエリと関係に対して、「default」という特殊なグループを使用します。デフォルトでは、default グループには、Bean のすべての cmp フィールドと、Bean の永続的な状態に外部キーを追加するすべての cmr フィールドが格納されます。

フィールドは複数のグループに関連付けられている場合があります。この場合、フィールドに対して getXXX() メソッドを実行すると、そのフィールドを含む最初のグループで障害が発生します。

フィールド グループの指定

フィールド グループは、weblogic-rdbms-cmp-jar.xml ファイルで次のように指定します。

<weblogic-rdbms-bean>
<ejb-name>XXXBean</ejb-name>
<field-group>
<group-name>medical-data</group-name>
<cmp-field>insurance</cmp-field>
<cmr-field>doctors</cmr-fields>
</field-group>
</weblogic-rdbms-bean>

フィールド グループは、フィールドのサブセットにアクセスする必要があるときに使用します。

 


自動主キー生成

WebLogic Server は、コンテナ管理による永続性 (CMP) 用の自動主キー生成機能をサポートしています。

生成されるキーのサポートは以下の 2 つの方法で提供されます。

注意: Oracle のテーブルの作成手順については、Oracle データベースのマニュアルを参照してください。

weblogic-cmp-rdbms-jar.xml ファイルで key_cache_size 要素を設定して、データベースの SELECT および UPDATE によって一度に取得する主キー値の数を指定します。key_cache_size のデフォルト値は 1 です。データベース アクセスを最小限に抑えてパフォーマンスを向上するために、BEA ではこの要素には値 >1 を設定することを推奨しています。この機能の詳細については、「主キーの命名済シーケンス テーブル サポートの指定」を参照してください。

現時点では、WebLogic Server は、Oracle および Microsoft SQL Server 向けの DBMS 主キー生成サポートだけを提供します。ただし、命名済シーケンス テーブルは、サポートされている他のデータベースで使用できます。また、この機能は単純 (非複合) 主キーで使用することを想定したものです。

有効なキー フィールド型

Bean の抽象「get」および「set」メソッドでは、以下の 2 つの型のいずれかとしてフィールドを宣言できます。

Oracle 用主キー サポートの指定

Oracle データベース用の主キー生成サポートでは、Oracle の SEQUENCE 機能が使用されます。この機能は、Oracle データベース内の Sequence エンティティと連携して一意の主キーを生成します。Oracle SEQUENCE は、新しい数値が必要な場合に呼び出されます。

SEQUENCE がデータベース内に作成されたら、XML デプロイメント記述子で自動キー生成を指定します。weblogic-cmp-rdbms-jar.xml ファイルで、次のように自動キー生成を指定します。

図6-3 Oracle 用自動キー生成の指定

<automatic-key-generation>
<generator-type>Oracle</generator-type>
<generator_name>test_sequence</generator-name>
<key-cache-size>10</key-cache-size>
</automatic-key-generation>

generator-name 要素で、使用する Oracle SEQUENCE の名前を指定します。Oracle SEQUENCESEQUENCE INCREMENT 値を付けて作成した場合は、key-cache-size を指定しなければなりません。この値は、Oracle SEQUENCE INCREMENT 値と一致する必要があります。これら 2 つの値が一致しない場合、重複キーの問題が発生する可能性が高くなります。

警告: Oracle では、ジェネレータ タイプ USER_DESIGNATED_TABLE を使用しないでください。使用すると、次の例外が発生する可能性があります。

Warning: javax.ejb.EJBException: nested exception is: java.sql.SQLException: Automatic Key Generation Error: attempted to UPDATE or QUERY NAMED SEQUENCE TABLE NamedSequenceTable, but encountered SQLException java.sql.SQLException: ORA-08177: can't serialize access for this transaction.

Warning: USER_DESIGNATED_TABLE モードは、TX ISOLATION LEVELSERIALIZABLE に設定します。Oracle では、これによって問題が発生する可能性があります。

Warning: 代わりに、Oracle では AutoKey オプションを使用します。

Microsoft SQL Server 用主キー サポートの指定

Microsoft SQL Server データベース用の主キー生成サポートでは、SQL Server の IDENTITY カラムが使用されます。Bean が作成され、新しい行がデータベース テーブルに挿入されると、SQL Server は、IDENTITY カラムとして指定されたカラムに、次の主キー値を自動的に挿入します。

注意: Microsoft SQL Server のテーブルの作成手順については、Microsoft SQL Server データベースのマニュアルを参照してください。

IDENTITY がデータベース テーブル内に作成されたら、XML デプロイメント記述子で自動キー生成を指定します。weblogic-cmp-rdbms-jar.xml ファイルで、次のように自動キー生成を指定します。

図6-4 Microsoft SQL 用自動キー生成の指定

<automatic-key-generation>
<generator-type>SQLServer</generator-type>
</automatic-key-generation>

generator-type 要素では、主キーの生成方法を指定します。

主キーの命名済シーケンス テーブル サポートの指定

サポートされていないデータベース向けの主キー生成サポートでは、Named SEQUENCE TABLE を使用してキー値を保持します。テーブルには、整数の SEQUENCE INT である単一カラムを持つ単一行を含める必要があります。このカラムは、現在のシーケンス値を保持します。

命名済シーケンス テーブル サポートを利用する場合、その基盤データベースがトランザクション アイソレーション レベル、TransactionSerializable をサポートしているか確かめます。weblogic-ejb.xml ファイルの isolation-level 要素にこのオプションを指定します。TransactionSerializable オプションは、あるトランザクションを複数回同時に実行することが、そのトランザクションを順番に複数回実行した場合と同じ結果になることを仕様とします。データベースで トランザクション アイソレーション レベル、TransactionSerializable がサポートされていなければ、命名済シーケンス テーブル サポートを使用できません。

注意: 基盤データベースでサポートされるアイソレーション レベルのタイプを判断するには、基盤データベースのマニュアルを参照してください。

NamedSequenceTable がデータベース内に作成されたら、次の例のように、weblogic-cmp-rdbms-jar.xml ファイル内の XML デプロイメント記述子を使用して自動キー生成を指定します。

図6-5 命名済シーケンス テーブル用の自動キー生成サポートの指定

<automatic-key-generation>
<generator-type>NamedSequenceTable</generator-type>
<generator_name>MY_SEQUENCE_TABLE_NAME</generator-name>
<key-cache-size>100</key-cache-size>
</automatic-key-generation>

generator-name 要素によって、使用する SEQUENCE TABLE の名前を指定します。key-cache-size を使用すると、1 回の DBMS 呼び出しでコンテナが取得するキーの数を示すキー キャッシュのサイズをオプションで指定することもできます。

パフォーマンスを向上するために、BEA ではこの値を >1 (1 より大きい) に設定することを推奨しています。この設定により、次のキー値を取得するためのデータベースの呼び出し回数を減らすことができます。

また、NAMED SEQUENCE テーブルは Bean のタイプごとに作成することをお勧めします。異なるタイプの Bean が NAMED SEQUENCE テーブルを共有しないようにしてください。こうすることで、キー テーブルの競合の発生を防ぎます。

 


自動データベース検出

このリリースより、WebLogic Server ではデータベースにクエリを実行することによって、アプリケーションで使用しているデータベースのタイプを検出するようになりました。WebLogic Server はこの情報を自動テーブル作成 (「自動テーブル作成」を参照)、EJB QL のコンパイル、EJB QL 文字列関数の対応する DMBS 固有の関数への変換、および EJB QL が外部結合を生成できるかどうかの判定に使用します。

WebLogic Server が検出するデータベース タイプが、weblogic-cmp-rdbms-jar.xmldatabase-type 要素で定義されたデータベース タイプと異なっている場合、WebLogic Server は警告を発行し、デプロイメント記述子で定義されているタイプを優先します。

 


自動テーブル作成

アプリケーション開発者がエンティティ Bean を開発する際には、基底のテーブル スキーマを変更する必要があります。自動テーブル生成機能を有効にすると、WebLogic Server EJB コンテナはエンティティ Bean の変更に合わせて自動的に基底のテーブル スキーマを変更し、テーブルが常にデプロイメント記述子の最新値を反映するようにします。

デプロイメント ファイルの記述に基づいてフィールドをデータベース内の適切なカラムの型にマップできない場合、CREATE TABLE は失敗し、エラーが送出されるので、テーブルを手動で作成する必要があります。

テーブルが既に存在する場合であっても、そのテーブルに追加された、またはそのテーブルから削除されたコンテナ管理による永続性フィールドがあれば、コンテナはデプロイメントの過程でテーブルを再作成します。確実にコンテナによって作成されたテーブルだけが変更されるように、コンテナで作成されたテーブルには、wls_temp という追加コラムが含まれています。

警告: プロダクション環境では自動テーブル作成を使用しないことをお勧めします。この機能は、設計および試作品の開発段階での使用が適しています。プロダクション環境では、外部キーの制約の宣言など、より正確なテーブル スキーマ定義を使用する必要があります。

自動テーブル作成の有効化

weblogic-cmp-rdbms-jar.xmlcreate-default-dbms-tables 要素を使用してこの機能を有効化します。この機能の動作は、次の表で説明するように、要素の値に応じて変わります。

この表に示す EJB コンテナのアクションは、すべてデプロイ中に発生します。

.

<create-default-dbms-tables> の設定値

得られる動作

Disabled

基底のテーブル スキーマが変更されても EJB コンテナはアクションを行わない。これがデフォルト値である。

CreateOnly

.jar に示される各 CMP Bean について、データベース内にその Bean のテーブルがなければ、コンテナはデプロイメント ファイルおよび Bean クラス内の情報に基づいて、テーブルを作成しようとする。テーブル作成が失敗した場合は、「Table Not Found」エラーが送出され、ユーザが手動でテーブルを作成することが必要となる。

DropAndCreate

.jar に示される各 CMP Bean について、カラムに変更があるとコンテナはテーブルを削除して作成する。

テーブルのカラムが変更されていなければ、コンテナはデータを保存する。カラムに変更があれば、コンテナはテーブルを削除して再作成し、すべてのテーブル データが失われる。

DropAndCreateAlways

.jar に示される各 CMP について、カラムに変更があってもなくても、コンテナはテーブルを削除して作成する。コンテナはデータを保存しない。

AlterOrCreate

.jar に示される各 CMP Bean について、テーブルが存在する場合、コンテナは 「ALTER TABLE」 SQL コマンドを使用してテーブル スキーマを変更しようとし、データを保存する。既存のテーブルがなければ、コンテナはデプロイメントの過程でテーブルを作成する。

注意: 以下の状況のいずれかに当てはまる場合は、このオプションを選択してはならない。

  • 主キーとして新しいカラムが指定されている

  • 新しい主キー カラムとして null 値を持つカラムが指定されている


 

自動テーブル作成で使用されるデータ型変換

自動テーブル作成を有効にした場合、WebLogic Server は自動データベース検出 (「自動データベース検出」を参照) 中に保存したデータ型の値を調べ、そのデータベースのテーブルを作成するために使用する正確な構文とデータ型変換について判断します。WebLogic Server では、以下のデータベースおよびベンダーにおけるベンダー固有の CREATE TABLE 構文とデータ型変換を使用します。

次の表では、自動テーブル作成で使用する、データベース ベンダごとのデータベース変換の概要を説明します。

Java の型

Oracle のカラム タイプ

SQL Server のカラム タイプ

Sybase のカラム タイプ

Informix のカラム タイプ

Pointbase のカラム タイプ

boolean






byte






char






double






float






int






long






short






プリミティブ バイトの配列 (byte[])






serializable

シリアライズ可能な java オブジェクトは、プリミティブ バイトの配列 (byte[]) にマップされる






java.lang.String






java.lang.BigDecimal






java.lang.Boolean






java.lang.Byte






java.lang.Character






java.lang.Double






java.lang.Float






java.lang.Integer






java.lang.Long






java.lang.Short






java.util.Date






java.sql.Date






java.sql.Time






java.sql.Timestamp







 

これら以外のすべてのデータベース システムの場合、WebLogic Server では基本的構文と次の表に示すデータ型変換を使用し、最適な方法で新しいテーブルを作成します。


 


 

表6-1 自動テーブル作成のための汎用データ型変換

Java の型

DBMS カラムの型

boolean

INTEGER

byte

INTEGER

char

CHAR

double

DOUBLE PRECISION

float

FLOAT

int

INTEGER

long

INTEGER

short

INTEGER

java.lang.string

VARCHAR (150)

java.lang.BigDecimal

DECIMAL (38, 19)

java.lang.Boolean

INTEGER

java.lang.Byte

INTEGER

java.lang.Character

CHAR (1)

java.lang.Double

DOUBLE PRECISION

java.lang.Float

FLOAT

java.lang.Integer

INTEGER

java.lang.Long

INTEGER

java.lang.Short

INTEGER

java.sql.Date

DATE

java.sql.Time

DATE

java.sql.Timestamp

DATETIME

byte[ ]

RAW (1000)

有効な SQL 型でないすべてのシリアライズ可能なクラス

RAW (1000)


 

 


Oracle の SELECT HINT の使用

WebLogic Server は、INDEX の使い方に関するヒントを Oracle Query オプティマイザに渡すことを可能にする EJB QL 拡張機能をサポートしています。この拡張機能を使用すると、データベース エンジンにヒントを提供できます。たとえば、検索先のデータベースが ORACLE_SELECT_HINT によって恩恵を受けることがわかっている場合は、ANY 文字列値を取り、その文字列値をデータベースに対するヒントとして SQL SELECT 文の後に挿入する ORACLE_SELECT_HINT 句を定義します。

このオプションを使用するには、この機能を使用するクエリを weblogic-ql 要素で宣言します。この要素は、weblogic-cmp-rdbms-jar.xml ファイルに入っています。weblogic-ql 要素では、EJB-QL に対する WebLogic 固有の拡張機能を含むクエリを指定します。

WebLogic QL のキーワードおよび使い方は次のとおりです。

SELECT OBJECT(a) FROM BeanA AS a WHERE a.field > 2 ORDERBY a.field SELECT_HINT '/*+ INDEX_ASC(myindex) */'

この文は、Oracle のオプティマイザ ヒントを使用して次の SQL を生成します。

SELECT /*+ INDEX_ASC(myindex) */ column1 FROM .... (etc)

WebLogic QL ORACLE_SELECT_HINT 句では、単一引用符で囲まれた部分 (' ') が SQL SELECT の後に挿入されます。クエリ作成者は、引用符内のデータを Oracle データベースが確実に認識できるものにする必要があります。「get」および「set」メソッドの制限

WebLogic Server では、一連のアクセサ メソッドを使用します。これらのメソッドの名前の先頭には、setget が付いています。WebLogic Server では、コンテナ管理によるフィールドの読み出しおよび修正にこれらのメソッドを使用します。コンテナによって生成されるこれらのクラスは、「get」または「set」で始まり、ejb-jar.xml で定義されている永続フィールドの実際の名前を使用する必要があります。また、これらのメソッドは、publicprotected、および abstract として宣言します。

 


複数のテーブル マッピング

EJB 2.0 CMP Bean における複数のテーブル マッピングを使用すると、1 つの EJB をあるデータベース内の複数の DBMS テーブルにマップできるようになります。その EJBの weblogic-cmp-rdbms-xml ファイルで、複数の DBMS テーブルとカラムを、EJB とこれのフィールドにマップすることによって、この機能をコンフィグレーションします。マッピングには次のタイプが含まれます。

複数のテーブル マッピングを有効にするには、次のことが必要になります。

これまでは、1 つの EJB を 1 つのテーブル、あるいは、フィールドやカラムの 1 リストに関連付けていました。現在は、EJB がマップするテーブルの数の分だけ、フィールドやカラムの一連のセットを 1 つの EJB にマップさせることができます。

1 つの Bean での複数のテーブル マッピングには次のような制限があります。

ある 1 つのエンティティ Bean にマップする複数のテーブルの主キー間に、参照一貫性制約を課してはなりません。この場合、Bean 削除時に実行時エラーになる可能性があります。

cmp-field の複数のテーブル マッピング

その EJB の weblogic-cmp-rdbms-xml ファイルの weblogic-rdbms-bean スタンザを使用し、cmp-field の複数のテーブル マッピングをコンフィグレーションする手順を次に示します。

  1. weblogic-cmp-rdbms-jar.xml ファイルの次の要素を指定します。

次の XML 例では、EJB を 1 つの DBMS テーブルにマップします。

図6-6 1 つの DBMS テーブルにマップする

<table-name>TableName</table-name>
<field-map>
<cmp-field>name</cmp-field>
<dbms-column>name_in_tablename</dbms-column>
</field-map>
	<field-map>
<cmp-field>street_address</cmp-field>
<dbms-column>street_address_in_tablename
</dbms_column>
</field-map>
<field-map>
<cmp-field>phone</cmp-field>
<dbms-column>phone_in_tablename</dbms-column>
</field-map>

次の XML 例では、EJB を 2 つの別のテーブルにマップします。

図6-7 2 つの DBMS テーブルにマップする

<table-map>
<table-name>TableName_1</table-name>
<field-map>
<!--Note ‘name’is the primary key field of this EJB -->
<cmp-field>name</cmp-field>
<dbms-column>name_in_tablename_1</dbms-column>
</field-map>
	<field-map>
<cmp-field>street_address</cmp-field>
<dbms-column>street_address_in_tablename_1
</dbms-column>
</field-map>
</table-map>
<table-map>
<table-name>TableName_2</table-name>
<field-map>
<!--Note ‘name’is the primary key field of this EJB -->
<cmp-field>name</cmp-field>
<dbms-column>name_in_tablename_2</dbms-column>
</field-map>
<field-map>
<cmp-field>phone</cmp-field>
<dbms-column>phone_in_tablename_2</dbms-column>
</field-map>
</table-map>

注意: テーブル マッピングを示した上記の XML 例でも分かるとおり、主キー フィールドを各テーブルの主キー カラムに必ずマップします。

コンテナ管理による関係 (CMR) フィールドに対する複数のテーブル マッピング

その EJB の weblogic-cmp-rdbms-xml ファイルの weblogic-relationship-role スタンザを使用し、cmr-field の複数のテーブル マッピングをコンフィグレーションする手順を次に示します。

  1. weblogic-cmp-rdbms-jar.xml ファイルの次の要素を指定します。

注意: cmr-field の複数のテーブルマッピングでは、ある関係を保持する外部キーを EJB を構成する複数のテーブルの中の 1 つのテーブルだけに置かなくてはなりません。

次の XML 例は、他の EJB と 1 対 1 関係を持つ EJB の cmr-field の複数のテーブル マッピングを示します。

図6-8 1 対 1 関係を持つ EJB のマッピング

<column-map>
<foreign-key-column>foreign_key_1</foreign-key-column>
<key-column>key_1</key-column>
</column-map>
<foreign-key-column>foreign_key_2</foreign-key-column>
<key-column>key_2</key-column>
</column-map>

次の XML 例で示す、ある EJB の cmr-field の複数のテーブル マッピングの例では、複数の外部キー カラムに明示的に名前が付けられています。

図6-9 relationship-role-name スタンザを使用した外部キー カラムのマッピング

<relationship-role-map>
<foreign-key-table>
<table-name>TableName_2</table-name>
</foreign-key-table>
<column-map>
<foreign-key-column>foreign_key_1
</foreign-key-column>
<key-column>key_11</key-column>
</column-map>
<column-map
<foreign-key-column>foreign_key_2
</foreign-key-column>
<key-column>key_12</key-column>
</column-map>
<column-map
<foreign-key-column>foreign_key_1
</foreign-key-column>
<key-column>key_21</key-column>
</column-map>
<column-map
<foreign-key-column>foreign_key_2
</foreign-key-column>
<key-column>key_22</key-column>
</column-map>
</relationship-role-map>

多対多関係のマッピングの場合は、次の点に注意します。

 

 Back to Top Previous Next