コンテナ管理による関係 (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>