Sun Java System Application Server Enterprise Edition 8.2 パフォーマンスチューニングガイド

コンテナ管理による関係 (CMR) Beans の先取り

コンテナ管理による関係 (CMR) がアプリケーションに存在する場合、ある Bean をロードすると、それに関連するすべての Beans がロードされます。CMR の典型的な例は、注文と注文明細の関係です。1 つの「Order」EJB コンポーネントと、それに関連する複数の「OrderLine」EJB コンポーネントが存在します。Application Server の以前のリリースでは、これらすべての Beans を使用するためには、複数のデータベースクエリーが必要でした。「Order」Bean に対するクエリーと、関係内の各「OrderLine」Beans に対するクエリーです。

一般に、1 つの Bean に n 個の関係がある場合、Bean のすべてのデータを使用すると n+1 回のデータベースアクセスが必要になります。CMR 先取りを使用して、Bean とそれに関係するすべての Beans のすべてのデータを、1 回のデータベースアクセスで取得します。

たとえば、ejb-jar.xml ファイルで次の関係が定義されているとします。

<relationships>
    <ejb-relation>
        <description>Order-OrderLine</description>
        <ejb-relation-name>Order-OrderLine</ejb-relation-name>
        <ejb-relationship-role>
            <ejb-relationship-role-name>
                Order-has-N-OrderLines
            </ejb-relationship-role-name>
            <multiplicity>One</multiplicity>
            <relationship-role-source>
                <ejb-name>OrderEJB</ejb-name>
            </relationship-role-source>
            <cmr-field>
                <cmr-field-name>orderLines</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
            </cmr-field>
        </ejb-relationship-role>
    </ejb-relation>
</relationships>

特定の Order がロードされるとき、アプリケーションの sun-cmp-mapping.xml ファイルに次の内容を追加することにより、それと関係を持つ OrderLine をロードできます。

<entity-mapping>
    <ejb-name>Order</ejb-name>
    <table-name>...</table-name>
    <cmp-field-mapping>...</cmp-field-mapping>
    <cmr-field-mapping>
        <cmr-field-name>orderLines</cmr-field-name>
        <column-pair>
            <column-name>OrderTable.OrderID</column-name>
            <column-name>OrderLineTable.OrderLine_OrderID</column-name>
        </column-pair>
        <fetched-with>
            <default>
        </fetched-with>
    </cmr-field-mapping>
</entity-mappping>

Order が取得されると、CMP エンジンは SQL を発行し、次の WHERE 句を持つ SELECT 文によって、すべての関係する OrderLine を取得します。

OrderTable.OrderID = OrderLineTable.OrderLine_OrderID

この句は外部結合を示します。これらの OrderLine は先取りされます。

一般的に、先取りを利用するとデータベースアクセスの数が減少するため、パフォーマンスが改善されます。ただし、ビジネスロジックでその OrderLine を参照することなく Order を頻繁に使用する場合、先取りはパフォーマンス面でのペナルティーとなる可能性があります。具体的には、実際には必要でない OrderLine を先取りする労力をシステムが費やしたことになります。

特定の検索メソッドについては、先取りを避けます。これにより、しばしばそのペナルティーを回避できます。たとえば、「Order」Bean に 2 つの検索メソッドがあると仮定します。OrderLine を使用する findByPrimaryKey メソッドと、注文情報のみを返し OrderLine を使用しない findByCustomerId メソッドです。OrderLine に対して CMR 先取りを有効にした場合、両方の検索メソッドが OrderLine を先取りします。ただし、配備記述子 sun-ejb-jar.xml に次の情報を含めることにより、findByCustomerId メソッドでの先取りを無効にすることができます。

<ejb>
    <ejb-name>OrderBean</ejb-name>
    ...
    <cmp>
        <prefetch-disabled>
            <query-method>
                <method-name>findByCustomerId</method-name>
            </query-method>
        </prefetch-disabled>
     </cmp>
</ejb>