第30章 CMP エンジン
本章では JBoss でのコンテナ管理による永続性 (CMP) の使い方について説明します。 EJB CMP モデルに関する基本的な知識があることを前提とし、JBoss CMP エンジンの操作方法を中心に解説します。特に、JBoss における CMP アプリケーションの設定と最適化を学びます。CMP の基本コンセプトなど初歩的な部分については、Enterprise Java Beans, Fourth Edition (O'Reilly 2004)を参照してください。
30.1. サンプルコード
本章はサンプルを使いながら進行します。架空の犯罪組織に関する情報を格納する犯罪ポータルアプリケーションを使用します。図30.1「犯罪ポータルのクラス例」にデータモデルを示します。
図30.1 犯罪ポータルのクラス例
犯罪ポータルのソースコードはサンプルコードの
src/main/org/jboss/cmp2
にあります。サンプルコードをビルドするには、以下のようにして Ant を実行します。
[examples]$ ant -Dchap=cmp2 config
このコマンドで JBoss サーバーにアプリケーションの構築およびデプロイを行います。 JBoss サーバーを起動する場合、あるいはすでに起動している場合、次のようなデプロイメントメッセージが表示されるはずです。
15:46:36,704 INFO [OrganizationBean$Proxy] Creating organization Yakuza, Japanese Gangsters 15:46:36,790 INFO [OrganizationBean$Proxy] Creating organization Mafia, Italian Bad Guys 15:46:36,797 INFO [OrganizationBean$Proxy] Creating organization Triads, Kung Fu Movie Extras 15:46:36,877 INFO [GangsterBean$Proxy] Creating Gangster 0 'Bodyguard' Yojimbo 15:46:37,003 INFO [GangsterBean$Proxy] Creating Gangster 1 'Master' Takeshi 15:46:37,021 INFO [GangsterBean$Proxy] Creating Gangster 2 'Four finger' Yuriko 15:46:37,040 INFO [GangsterBean$Proxy] Creating Gangster 3 'Killer' Chow 15:46:37,106 INFO [GangsterBean$Proxy] Creating Gangster 4 'Lightning' Shogi 15:46:37,118 INFO [GangsterBean$Proxy] Creating Gangster 5 'Pizza-Face' Valentino 15:46:37,133 INFO [GangsterBean$Proxy] Creating Gangster 6 'Toohless' Toni 15:46:37,208 INFO [GangsterBean$Proxy] Creating Gangster 7 'Godfather' Corleone 15:46:37,238 INFO [JobBean$Proxy] Creating Job 10th Street Jeweler Heist 15:46:37,247 INFO [JobBean$Proxy] Creating Job The Greate Train Robbery 15:46:37,257 INFO [JobBean$Proxy] Creating Job Cheap Liquor Snatch and Grab
サンプルの bean はデプロイを解除するとテーブルが削除されるよう設定されているため、JBoss サーバーを起動すると必ず設定ターゲットに戻り、サンプルデータの再ロードとアプリケーションの再デプロイを行う必要があります。
30.1.1. CMP デバッグロギングの有効化
本章のテストで有用なフィードバックを取得するためには、テストを実行する前に CMP サブシステムのログレベルを上げておきます。デバッグロギングを有効にするには、次のカテゴリを
log4j.xml
ファイルに追加します。
<category name="org.jboss.ejb.plugins.cmp"> <priority value="DEBUG"/> </category>
また、
CONSOLE
アペンダーのしきい値を下げ、コンソールにデバッグレベルのメッセージが記録されるように設定します。 次の変更も log4j.xml
ファイルに適用する必要があります。
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="DEBUG" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message
-->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
CMP エンジンが完全に起動していることを確認するには、以下に示すように
org.jboss.ejb.plugins.cmp
カテゴリでカスタムの TRACE
レベル優先度を有効にする必要があります。
<category name="org.jboss.ejb.plugins.cmp"> <priority value="TRACE" class="org.jboss.logging.XLevel"/> </category>
30.1.2. サンプルの実行
最初のテストターゲットでは、本章で説明するカスタマイズ機能を示します。これらのテストを実行するには、次の ant ターゲットを実行します。
[examples]$ ant -Dchap=cmp2 -Dex=test run-example
22:30:09,862 DEBUG [OrganizationEJB#findByPrimaryKey] Executing SQL: SELECT t0_OrganizationEJ B.name FROM ORGANIZATION t0_OrganizationEJB WHERE t0_OrganizationEJB.name=? 22:30:09,927 DEBUG [OrganizationEJB] Executing SQL: SELECT desc, the_boss FROM ORGANIZATION W HERE (name=?) 22:30:09,931 DEBUG [OrganizationEJB] load relation SQL: SELECT id FROM GANGSTER WHERE (organi zation=?) 22:30:09,947 DEBUG [StatelessSessionContainer] Useless invocation of remove() for stateless s ession bean 22:30:10,086 DEBUG [GangsterEJB#findBadDudes_ejbql] Executing SQL: SELECT t0_g.id FROM GANGST ER t0_g WHERE (t0_g.badness > ?) 22:30:10,097 DEBUG [GangsterEJB#findByPrimaryKey] Executing SQL: SELECT t0_GangsterEJB.id FRO M GANGSTER t0_GangsterEJB WHERE t0_GangsterEJB.id=? 22:30:10,102 DEBUG [GangsterEJB#findByPrimaryKey] Executing SQL: SELECT t0_GangsterEJB.id FRO M GANGSTER t0_GangsterEJB WHERE t0_GangsterEJB.id=?
これらのテストでは、マッピングの問題に関して各種の finder、selector、object を実行させます。本章ではこれらのテストについて見ていきます。
その他メインターゲットは 「最適化ローディング」 に記載されている最適化ローディング設定を行うテスト一式を実行します。これでログ機能が正しく設定され、read-ahead テストは実行したクエリーに関する便利な情報を表示するようになります。log4j.xml ファイルに対する変更を認識させるのに JBoss サーバーを起動する必要はありませんが、反映されるのに 1 分ほどかかる場合があります。 readahead クライアントの実際に実行したものを以下に示します。
[examples]$ ant -Dchap=cmp2 -Dex=readahead run-example
readahead クライアントを実行すると、テスト中に実行される SQL クエリはすべて JBoss サーバーコンソールに表示されます。出力を分析する場合、実行されるクエリ数、選択したカラム、ロードされる行数に着目してください。次に readahead からの JBoss サーバーコンソール出力で read-ahead none の部分を示します。
22:44:31,570 INFO [ReadAheadTest] ######################################################## ### read-ahead none ### 22:44:31,582 DEBUG [GangsterEJB#findAll_none] Executing SQL: SELECT t0_g.id FROM GANGSTER t0_ g ORDER BY t0_g.id ASC 22:44:31,604 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,615 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,622 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,628 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,635 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,644 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,649 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,658 DEBUG [GangsterEJB] Executing SQL: SELECT name, nick_name, badness, organization , hangout FROM GANGSTER WHERE (id=?) 22:44:31,670 INFO [ReadAheadTest] ### ######################################################## ...
このサンプルについては、最適化ローディングの設定の際に再度検証します。