第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] 
###
########################################################
...
このサンプルについては、最適化ローディングの設定の際に再度検証します。