ejb 3.0 への移行otndnld.oracle.co.jp/.../oc4j-twp-ejb3-migration-1013.pdfejb 3.0 への移行...

21
EJB 3.0 への移行 Oracle ホワイト・ペーパー 2005 10

Upload: phungdat

Post on 23-Jul-2018

225 views

Category:

Documents


1 download

TRANSCRIPT

EJB 3.0 への移行

Oracle ホワイト・ペーパー 2005 年 10 月

EJB 3.0 への移行

2

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

EJB 3.0 への移行

移行が必要な理由 ................................................................................... 4 EJB 3.0 における変更点..................................................................................... 4 Session Bean の移行 ............................................................................................ 5

Session Bean の変更 ...................................................................................... 5 Session Bean を使用するアプリケーション・コードの移行 ................... 7

Message-Driven Bean(MDB)の移行 .............................................................. 8 EJB 3.0 の永続化への移行................................................................................. 9

新しい永続化 API.................................................................................... 9 EJB 2.x CMP Entity Bean の移行 .................................................................. 9

DTO と EJB 3.0 エンティティ ............................................................. 10 DTO の EJB 3.0 エンティティへの移行.............................................. 11 EJB 2.x Entity Bean の移行.................................................................... 12 EJB 2.x エンティティ・ホームの移行................................................ 16 ライフサイクル・メソッドの移行 ..................................................... 17 O-R マッピングの移行 ......................................................................... 17 例外処理 ................................................................................................. 18 CMP クライアント・アプリケーション・コードの移行 ................ 18

CMP クライアントの移行 ......................................................................... 18 POJO アプリケーションの移行 ................................................................ 19

結論 .................................................................................................................... 19

EJB 3.0 への移行

3

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

EJB 3.0 への移行

Enterprise JavaBeans(EJB)のプログラミング・モデルは、EJB 3.0 で飛躍的に簡素

化されており、サーバー側のビジネス・ロジック・プログラミングの新しい標準

として Java 開発者から歓迎されています。一方で、以前のバージョンの EJB APIを使用して作成された J2EE アプリケーションの数は数千にも及ぶため、相互運用

性と EJB 3.0 を使用するためのアプリケーションの移行について、不安が広がって

います。このホワイト・ペーパーでは、これらの問題に関連するさまざまな内容

について説明します。

オラクルが提供する EJB 3.0 の機能につ

いては、otn.oracle.com/ejb3 を参照して

ください。

移行が必要な理由

EJB 3.0対応の J2EEコンテナへのアップグレードを計画する場合、なぜアプリケー

ションを移行する必要があるのかという問題について、J2EE プロジェクトの参加

者で議論する必要があります。オラクルをはじめとする、すでに EJB 3.0 機能を提

供している大手アプリケーション・サーバー・ベンダーでは、新しいEJB 3.0 コンテナ

でも引き続きEJB 2.xをサポートする予定です。つまり、EJB 2.xで記述されたアプリケー

ションは、まったく変更しなくても今後も実行できるのです。しかし、EJB 3.0 API を使用するためにアプリケーションの移行を希望する組織も実際にあります。

EJB 2.x から移行することで得られる利点には、以下が含まれます。

• EJB を取り囲む複雑さの軽減。インタフェース、ホーム・インタフェー

ス、およびメタデータが大幅に簡素化されます。

• エンティティやエンティティを使用するコンポーネントの容易なテスト。

EJB 2.x の永続化ソリューションでは、ほとんどのアプリケーションで重

要なユニット・テストが行われていませんでした。

• EJB 2.x Entity Bean の制限を回避するための、問題が発生しやすいコード

の削減。これらのパターンには、データ転送オブジェクト(DTO)や Service Locator の実装が含まれます。

上記の利点は、開発者の生産性、アプリケーション品質、およびメンテナンス・

コストに重要な影響を与えます。ここで課題となるのは、これらの利点と移行に

かかるコストを把握した上で、アプリケーションの開発サイクルのどの時点でこ

の移行を実行することがもっとも効率的であるかを判断することです。

EJB 3.0 における変更点 EJB 3.0 の主要な目標は、プログラミング・モデルを簡素化することと、Java プラッ

トフォーム向けの永続化 API を定義することにあります。EJB 開発を容易にする

ための EJB の主な変更点は次のとおりです。

EJB 3.0 への移行

4

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

• EJB 3.0 では、Plain Old Java Object(POJO)が使用されます。

• XML ディスクリプタが不要になり、代わりにアノテーションが使用され

ます。

• 可能な限り、デフォルトが設定されます。

• 不要なアーチファクトやライフサイクル・メソッドを定義する必要がな

くなりました。

• 依存性の注入によりクライアント・ビューが簡素化されました。

POJO の永続化モデルが J2EE のコンテキスト内で標準化されたことにより、今ま

でコンテナの外部や自社製品でしか使用できなかった継承やポリモフィズムが使

用できるようになります。さらに、POJO の Entity Bean を EJB コンテナの内部と

外部の両方で使用し、テストできるようになりました。

EJB 3.0 に関する最新情報については、Sunのドラフト仕様を参照してください。

Session Bean の移行 EJB 3.0 の Session Bean における主要な変更の目的は、開発を容易にすることにあ

ります。これは、Bean を POJO にし、XML ディスクリプタに加えてアノテーショ

ンも使用可能にするとともに、JNDI ルックアップの代わりに依存性の注入を提供

することで実現されます。この移行に伴って発生する変更には、Bean 自体の変更

と Bean を使用するアプリケーション・コードの変更があります。

Session Bean の変更

EJB 3.0 へ移行するために必要な EJB 2.x の Session Bean の変更には、次が含まれ

ます。

• リモートおよびローカルのインタフェースで、javax.ejb.EJBObject

または javax.ejb.EJBLocalObject を実装する必要がなくなりまし

た。コンポーネント・インタフェースはビジネス・インタフェースとし

て使用できます。また、アノテーション@Remote を使用すると、インタ

フェースがリモート・クライアントからアクセス可能であることを示す

ことができます。

• リモート・インタフェース上のメソッドから RemoteExceptions をスロー

する必要がなくなりました。リモート EJB 2.x の Session Bean の簡単な例

を次に示します。

public interface HelloWorld extends EJBObject {

String sayHello(String name) throws RemoteException;

}

When migrated to EJB 3.0 the remote interface is simply:

@Remote public interface HelloWorld {

String sayHello(String name);

}

EJB 3.0 への移行

5

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

• Bean クラスが実装するのは、javax.ejb.SessionBean ではなくビジネス・イ

ンタフェースです。この結果、Bean に不要なライフサイクル・メソッド

を実装する必要がなくなりました。代わりに、必要なライフサイクル・

コールバックはアノテーションを使用して示されます。

次に、簡単な EJB 2.x のステートレス Session Bean を表す Bean クラスを示し

ます。 public class HelloWorldBean implements SessionBean {

public void ejbCreate() {} public void ejbActivate() {} public void ejbPassivate() {} public void ejbRemove() {} public void setSessionContext(SessionContext ctx) {} public String sayHello(String name) {

return "Hello " + name;

}

}

EJB 3.0 に移行すると、Bean クラスは次のようになります。 @Stateless public class HelloWorldBean implements HelloWorld {

public String sayHello(String name) {

return "Hello " + name;

}

}

• ステートフル Session Bean の場合、ejbCreate メソッドは、コンテナが維持

する必要のあるステートを初期化するビジネス・メソッドに置き換えられ

ます。たとえば、次のように、ビジネス・メソッドを作成し、@PostConstructを使用してアノテートできます。

@PostConstruct public void initialize() {

items = new ArrayList();

}

ステートフル Bean がアプリケーションで不要になったことをコンテナに

示す削除メソッドは、@Remove を使用してアノテートします。

• トランザクションおよびセキュリティ用のアノテーションを使用するた

めの Session Bean コードの移行は、任意で行います。

EJB 3.0 への移行

6

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

Session Bean を使用するアプリケーション・コードの移行

Bean 自体の変更に加えて、Session Bean を使用するアプリケーション・コードを

移行する必要があります。これには、別の J2EE および J2SE コンポーネント内で

使用されるアプリケーション・コードも含まれます。EJB 3.0 では、依存性注入の

原則を導入することによって、リソースや EJB 参照が簡単に使用できます。リソー

スや参照の注入は、注入ターゲットのアノテーションまたは ejb-jar.xml ディスク

リプタ内のターゲットの指定を介して実行されます。

EJB 2.x EJB 3.0

別の EJB の使用:

• XML ディスクリプタ内の ejb-ref

• JNDI ルックアップによるホーム・

インタフェースの取得

• home.create の呼び出しによるイン

スタンスの取得

別の EJB の使用:

• ejb-ref にホーム・インタフェース

は不要

• ホーム・インタフェースから移行

されたビジネス・インタフェース

への変更

• home.create の削除と EJB メソッド

の直接起動

• EJB ビジネス・インタフェースの

プロパティやフィールドのアノ

テートによるインスタンスの取得

(任意)

リソース・アクセス

• JNDI ルックアップによるリソース

の取得

リソース・アクセス

• リソースのプロパティやフィール

ドのアノテートによるリソースの

取得(任意)

たとえば、別のEJB 2.1 Bean でCartEJB を使用している場合、デプロイメント・ディス

クリプタ内で ejb-ref を使用して CartEJB への参照を定義する必要があります。 <ejb-ref-name>MyCart</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>CartHome</home> <remote>Cart</remote>

次に、JNDI を使用して CartEJB のホーム・インタフェースを検索すると、CartEJBのインスタンスが作成できます。

Object homeObject = context.lookup("java:comp/env/MyCart"); CartHome home =(CartHome)PortableRemoteObject.narrow(homeObject,

CartHome.class);

EJB 3.0 への移行

7

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

Cart cart =(Cart)PortableRemoteObject.narrow(home.create(),

Cart.class); cart.addItem("Item1");

EJB 3.0 の注入パターンへ移行した後は、依存性注入を利用することでこのコード

は非常に簡単になります。 @EJB Cart cart; public void addItems() {

cart.addItem("Item1"); }

また、CMP Entity Bean のファサードとして Session Bean を使用することもできる

ため、CMP Entity Bean から EJB 3.0 の永続化 API へと移行する動きが高まってい

ます。

Message-Driven Bean(MDB)の移行 EJB 3.0 の MDB では、javax.ejb.MessageDriven インタフェースを実装する必要はな

くなりました。代わりに、@MessageDriven を使用してアノテートできます。Session Bean と同じ方法で、リソースや EJB 参照を MDB に注入できます。同様に、コン

テキスト(MDBのMessageDrivenContext)をMessage-Driven Beanに注入できます。

次の表に、EJB 2.x と EJB 3.0 での MDB の変更点をまとめます。

EJB 2.x EJB 3.0

javax.ejb.MessageDriven

の実装

@MessageDriven

を使用したアノテート

デプロイメント・ ディスクリプタ内で宛先タイプ、 名前などを指定

@ActivationConfigProperty

を使用したアノテートが可能

SetMessageDrivenContext()

による MessageDrivenContext の取得

依存性注入を使用した MessageDrivenContext の取得。

例:

@Resource javax.ejb.MessageDrivenContext mc;

Queue や Topic などのリソースの使

用には、デプロイメント・ディスク

リプタ内での resource-ref と JNDIルックアップが必要

依存性の注入を使用して実行可能。例:

@Resource(name="jms/myQueue")

private QueueConnectionFactory

queueConnectionFactory;

EJB 3.0 への移行

8

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

EJB 3.0 の永続化への移行 永続化は、J2EE 開発者が直面している最大の課題の 1 つです。Enterprise Java プ

ラットフォームには標準の永続化 API が欠如しているため、この問題はさらに悪

化しています。通常、J2EE アプリケーションは次のいずれかの方法で永続化を実

現しています。

• EJB 2.x コンテナ管理永続性(CMP)Entity Bean

• Oracle TopLink™、JBoss Hibernate™、またはカスタムの O-R マッピング・

フレームワークなどの POJO 永続化フレームワーク

• JDBC を使用したデータ・アクセス・オブジェクト

• Java データ・オブジェクト

EJB 3.0 で定義されている新しい永続化 API では、これらの選択肢すべてをまとめ

た待望の標準が提供されます。どの永続化手法を使用しているかによって、移行

の課題と機会はそれぞれ異なります。このホワイト・ペーパーでは、EJB 2.x CMPからの移行に重点を置いて説明します。この移行には飛躍的な変更が必要であり、

2.x 仕様で定義した現在のソリューションを採用している顧客に影響を与えるため

です。

新しい永続化 API

新しい永続化APIの中心となるのは、EntityManagerです。EntityManagerは

アプリケーションが使用するプライマリ・インタフェースであり、永続化エンティ

ティの取得と変更を行います。このインタフェースがJ2EEコンポーネント内で使

用できることに加えて、新しい永続化APIでは、EJB 3.0 の統合コンテナの外部サ

ポートが提供されます。

このサポートは Application Managed と呼ばれており、コンテナ外部でアプリケー

ション・コードと EJB コンポーネントをテストすることを主な目的とするととも

に、その他の機能も提供しています。これにより、開発者は、単純なテスト・ケー

スを作成して、エンティティとその関連コードの動作を検証できるようになりま

す。これは、永続化 API がもたらすもっとも顕著な利点の 1 つです。

EJB 2.x CMP Entity Bean の移行

EJB 2.x の永続性を EJB 3.0 へ移行するプロセスは、両者の共存から完全な移行と

新手法の導入まで多岐にわたります。移行には、モデル、そのマッピング、問合

せ、および永続化 API を使用するアプリケーション・コードに対する変更が含ま

れます。

移行には、次の 3 つの基本的な手法があります。

1. エンティティ DTO を EJB 3.0 エンティティへ移行する

2. EJB 2.x の Entity Bean を EJB 3.0 エンティティへ移行する

3. 新しい EJB 3.0 のエンティティ・モデルを作成する

はじめの 2 つの手法は、アプリケーション・コードの変更を最小限に抑えること

を目的としています。3 番目の手法は、新しいモデルを作成することにより、コー

ディングと設定作業を削減することを目的としています。この手法では、自動生

成ツールを使用する場合があります。この方法は、EJB 3.0 の永続化モデルを構築

するための最適な方法ですが、アプリケーション・コードの移行コストはもっと

も高くなります。

EJB 3.0 への移行

9

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

DTO と EJB 3.0 エンティティ

特定のアプリケーションにとってどれが最適な手法であるかを取り上げる前に、

DTOに関する課題と EJB 3.0の永続性においてDTOが果たす役割について明らか

にしておく必要があります。EJB 2.x では、アプリケーションの別の層で使用する

際コンテナの外部で永続化データを取得するために、DTO が必要でした。EJB 3.0のエンティティはシリアライズ可能であるため、DTO を使用する必要はなくなり

ました。これgは、必要とされる分離機能を提供している場合でも DTO を使用で

きないということではありません。ただし、一般的に行われている、Entity Beanのミラー化やビジネス・ロジックのレプリケーションを目的とした DTO の使用は

解消されます。これらの"エンティティ DTO"と呼ばれる DTO は、もはや必要あり

ません。

DTO が果たすもう 1 つの役割は、"ビューDTO"です。ビューDTO は、CMP エン

ティティをミラー化しないオブジェクトで、代わりに 1つまたは複数のEntity Beanから取得した、よりおおまかなデータ・ビューを提供します。また、異なる階層

間での相互作用を最適化するために使用されます。EJB 3.0 でもこのようなタイプ

の DTO の必要性はなくなりませんが、EJB 3.0 が提供する機能によって、より簡

単に使用できるようになります。従来のアプリケーションでは、根底にあるエン

ティティを取得してから、プログラムを使用してビューDTO にデータを挿入する

必要がありましたが、EJB 3.0 の問合せの結果は、バインディング・コードを追加

しなくてもビューDTO に直接反映されます。

EJB 3.0 の EJB QL クエリーでは、非永続クラスを使用して結果が返されます。こ

の場合、問合せ文により必要な属性と永続化モデルに関連する選択基準が定義さ

れますが、これらの 1 つが返される代わりに、非永続クラスが指定されます。こ

の指定に使用される NEW 演算子は、クラスと、結果オブジェクトの構築に使用

されるコンストラクタを定義します。 SELECT

NEW EmpView(e.id, e.firstName, e.lastName, d.name) FROM Employee e JOIN e.department d WHERE e.salary > 50000

エンティティ DTO から EJB 3.0 エンティティへの移行を選択すると、これらのシ

リアライズしたオブジェクトを使用するクライアント層の変更を最小限に抑える

ことができます。また、EJB 層に含まれるアプリケーション・ロジックがごくわ

ずかであるか、またはエンティティ DTO に集中している場合も、この移行を選択

してください。

この手法では、エンティティDTOが有効な JavaBeanであり、関連づけられたEntity Bean のデータ要素と 1 対 1 の対応関係を維持している必要があります。また、DTOを変換した後に永続化ロジックを単独で更新できるように、DAO 層を配置するこ

とが強く推奨されています。アプリケーション・ロジックで EJB 2.x エンティティ

を直接使用している場合は、Entity Bean の移行の項で説明したテクニックの方が

適している場合もあります。

EJB 3.0 への移行

10

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

DTO の EJB 3.0 エンティティへの移行

移行プロセスの最初のステップは、クラス定義に@Entity アノテーションを追加す

ることにより、エンティティ DTO を永続化オブジェクトとして指定することです。

EJB 3.0 のデフォルトでは、これだけでエンティティ DTO がデータベースにマッ

ピングされる永続化オブジェクトになります。デフォルトでは、表の名前はクラ

ス名と同じであり、JavaBean に含まれる public の getter メソッドは、それぞれプ

ロパティと同じ名前を持つ表の列に一致するとみなされます。@Table、@Column、及びその他の EJB 3.0 アノテーションを使用して、これらのデフォルトのマッピン

グをカスタマイズできます。

各エンティティ DTO を永続化オブジェクトとして指定し、データベース・マッピ

ングを適切に設定した後、次のステップとして、新しいエンティティ間の関係を

定義します。EJB 3.0 にはオブジェクト・リレーショナル・アノテーションの完全

な一式が含まれており、エンティティ関係を識別するとともに永続化操作におけ

る動作を制御します。EJB 2.x の ejb-jar.xml ファイルに含まれる<ejbrelation>ディ

スクリプタは、関係を持つエンティティの各ペアに直接マッピングできます。次

のリレーションシップ・ディスクリプタについて検討します。 <ejb-relation>

<ejb-relation-name>Dept-Emps</ejb-relation-name> <ejb-relationship-role>

<ejb-relationship-role-name>Dept-has-Emps

</ejb-relationship-role-name>

<multiplicity>One</multiplicity> <relationship-role-source>

<ejb-name>DeptBean</ejb-name>

</relationship-role-source> <cmr-field>

<cmr-field-name>employees</cmr-field-name> <cmr-field-type>java.util.Set</cmr-field-type>

</cmr-field> </ejb-relationship-role>

<ejb-relationship-role>

<ejb-relationship-role-name>

Emps-have-Dept

</ejb-relationship-role-name> <multiplicity>Many</multiplicity> <relationship-role-source>

EJB 3.0 への移行

11

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

<ejb-name>EmpBean</ejb-name>

</relationship-role-source> <cmr-field>

<cmr-field-name>dept</cmr-field-name>

</cmr-field>

</ejb-relationship-role>

</ejb-relation>

次の Employee エンティティの一部は、Emps-have-Dept ロールがどのようにマッピ

ングされるかを示します。 @Entity public class Employee {

private Department department; // ... @ManyToOne public Department getDepartment() {

return department;

} public void setDepartment(Department dept) {

this. department = dept;

}

}

表名やフィールド名がデフォルトで設定され、上書きできるのと同様に、外部キー

の列名もデフォルト設定されます。これに対して、リレーションシップ・マッピ

ング・アノテーションでは、@JoinColumn を使用してデフォルトとは異なる列名

を提供します。

この時点では、既存アプリケーションの動作で変更はないことに注意してくださ

い。ここまでで実行したことは、もとのエンティティ DTO にメタデータを追加し

て、これらを EJB 3.0 の永続化エンティティとして使用可能にしただけです。エン

ティティ DTO を管理する DAO 層が適切に配置されている場合、この層を更新す

ることにより、EntityManager を使用して新しくアノテートされた永続化オブジェ

クトの取得、格納、更新を行うことができます。

EJB 2.x Entity Bean の移行

DTOをエンティティへ移行するためのもう1つの方法は、既存のEJB 2.xのエンティ

ティ・モデルを活用することです。説明のため、ここでは Entity Bean のローカル・

インタフェースのみが使用されていることにします。これは、ローカル・インタ

フェースが現在のアプリケーションにもっとも普及しており、リモート・オブジェ

クトとしてのエンティティは EJB 3.0 ではサポートされていないためです。アプリ

ケーションがリモート・オブジェクトとして Entity Bean を使用している場合、移

行にはより抜本的な設計変更が必要になります。

EJB 3.0 への移行

12

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

このタイプの移行の目的は、エンティティのローカル・インタフェースとホーム・

インタフェースに結合しているクライアント・コードの変更を最小限に抑えるこ

とにあります。

1. Bean クラスでの抽象的な指定を排除し、プロパティ・アクセッサ(get/set)メソッドの明確な実装を行います。

2. エンティティをデータベースにマッピングするオブジェクト・リレーショ

ナル・アノテーションを Bean クラスに指定し、この関係を記述します。

3. Bean クラスの名前をローカル・インタフェースの名前に変更し、ローカ

ル・インタフェースを削除します。これにより、このインタフェースを介

して Bean を使用しているアプリケーション・コードへの変更が最小限に

抑えられます。

4. Bean に関連づけられたファインダと select を、Bean クラスの@NamedQueryアノテーションに変換します。

エンティティ Bean が別の Bean のクライアントとして機能している場合、後述の

とおり、このコードをアプリケーション・クライアント・コードとして移行する

必要があります。

次の EJB 2.x の Department Bean について検討します。 public abstract class DepartmentBean implements EntityBean {

public abstract Long getId(); public abstract void setId(Long id); public abstract String getName(); public abstract void setName(String name); public abstract Collection getEmployees(); public abstract void setEmployees(Collection employees); public void ejbCreate(Long id) throws CreateException {} public void ejbPostCreate(Long id) throws CreateException {} public void ejbStore() {} public void ejbLoad() {} public void ejbRemove() throws RemoveException {} public void ejbActivate() {} public void ejbPassivate() {} public void setEntityContext(EntityContext ctx) {} public void unsetEntityContext() {}

}

上記は、次のファインダ定義に基づいています。

EJB 3.0 への移行

13

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

<query>

<description></description> <query-method>

<method-name>findAll</method-name> <method-params/>

</query-method> <result-type-mapping>Local</result-type-mapping> <ejb-ql>Select OBJECT(d) From Department d</ejb-ql>

</query> <query>

<description></description> <query-method>

<method-name>findByDeptName</method-name> <method-params>

<method-param>java.lang.String</method-param>

</method-params>

</query-method> <result-type-mapping>Local</result-type-mapping> <ejb-ql>SELECT DISTINCT OBJECT(d) FROM Department d WHERE

d.name = ?1</ejb-ql> </query>

上記のステップに続いて、最後に次の処理を実行します。 @Entity @Table(name="DEPT") @NamedQueries({

@NamedQuery(name="DepartmentFindAll",

queryString="SELECT OBJECT(d) FROM Department d"),

@NamedQuery(name="DepartmentFindByName",

queryString="SELECT OBJECT(d) FROM Department d

WHERE d.name=?1")

})

public class Department {

EJB 3.0 への移行

14

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

private long id; private String name; private Collection<Employee> employees; public Department() {} @Id public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany public Collection getEmployees() { return employees; } public void setEmployees(Collection employees) {

this.employees = employees;

}

}

特に重要なのは、EJB 2.x のコンテナ管理リレーションシップ(CMR)が使用され

ていることです。EJB 3.0 では、リレーションシップ管理は標準の Java コーディン

グ・プラクティスを使用して実行されています。リレーションシップが形成され

た場合、リレーションシップの両方が正しく更新されるようにすることは、開発

者の責任になります。一般的に、モデルの一貫性を維持するには、リレーション

シップの処理を行うごとにコードを 1 行追加する必要があります。コレクション

に関しては、クライアント・コードでコレクションを直接操作する代わりに、addや eremove などのヘルパー・メソッドを使用することが推奨されています。

@Entity public class Department {

private Collection<Employee> employees; public void addEmployee(Employee emp) {

employees.add(emp); emp.setDepartment(this);

}

}

移行の際、これらの一般的な変更に加えて、EJB 2.x の Entity Bean 実装に関する作業

が必要となる場合があります。これらの作業には、Bean 自体の中での EntityContextの使用と、ejbHome メソッドの使用が含まれます。EJB 3.0 のエンティティには、

EntityContext は含まれません。エンティティは、単純に"this"を使用して自身を解

決してから、別の Bean のメソッドに渡します。実装済みの ejbHome メソッドは、

そのままにしておくか、または使用していることが明らかになるように静的メ

ソッドに変換します。

EJB 3.0 への移行

15

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

EJB 2.x エンティティ・ホームの移行

ホーム・インタフェースは、Entity Bean のロケーティングや管理を行うアプリケー

ション・コードを有効化する主要なメカニズムです。EJB 3.0 では、ホーム・イン

タフェースに相当するものが提供されないため、移行における最大の課題がここ

に生じます。

クライアント・コードへの変更を最小限に抑えるためのもっとも容易なホームの

移行方法は、EntityManager を保持するヘルパー・クラスを作成し、ホーム上でア

プリケーション・コードから呼び出されるメソッドを実装することです。

次に、ホームの代わりの役割を果たすヘルパー・クラスの例を示します。 public class DepartmentHome {

private EntityManager em; public DeptHome(EntityManager em) {

this.em = em;

} public Department create(long id) {

Department dept = new Department(id); em.persist(dept);

} public void remove(Department dept) {

em.remove(dept);

} public Department findByPrimaryKey(long id) {

return em.find(Department.class, id);

} public Department findByName(String name) {

return (Department)

em.createNamedQuery(-DepartmentFindByName")

.setParameter(0, name) .getSingleResult();

} public Collection findAll() {

EJB 3.0 への移行

16

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

return em.createNamedQuery(-DepartmentFindAll")

.listResults();

}

}

このヘルパー・クラスでは、ファインダを実装するためにエンティティ・クラス

で定義した名前付き問合せを利用していますが、動的な問合せを使用することも

できます。このヘルパーの remove メソッドは、これまで Entity Bean に含まれて

いた EJBLocalObject.remove()に取って代わります。Bean の remove メソッドに対す

るすべてのコールは、ヘルパーの remove メソッドへのコールに変更するか、また

は EntityManager を使用して直接コールするように変更する必要があります。

ライフサイクル・メソッドの移行

EJB 2.x では、ライフサイクル・メソッド一式を定義した EntityBean インタフェー

スを実装するには厳しい要件がありました。これらのライフサイクル・イベント

には、EJB 3.0 で適用されなくなったものもあります。

次の表に、これらのメソッドをすでに実装している場合に推奨される移行方針を

示します。

EJB 2.x のライフサイクル・メソッド EJB 3.0 での処理

EjbCreate init メソッドまたはコンストラクタ内に ロジックを実装

EjbPostCreate コンストラクタ内にロジックを実装、 またはビジネス・メソッドの作成と @PostPersist によるアノテート

EjbRemove ビジネス・メソッドの作成と@PreRemove によるアノテート

setEntityContext unSetEntityContext 適用なし

EjbActivate ビジネス・メソッドの作成と@PostLoad によるアノテート

EjbPassivate 適用なし(削除可)

EjbStore ビジネス・メソッドの作成と@PrePersist または@PreUpdate によるアノテート

O-R マッピングの移行

EJB 3.0 以前の O-R マッピングは常にベンダーの領域に含まれていたため、通常、

ベンダー固有のデプロイメント・ディスクリプタ内に格納されていました。現在、

O-R マッピングは EJB 標準に統合され、Bean クラスのアノテーションとして、ま

たは標準 XML ファイル内に定義できます。ほとんどのベンダーから、このマッ

ピングを標準の EJB マッピングに変換する方法が提供されており、自動化された

移行ツールまたはマッピング・エディタを使用して実行できます。

EJB 3.0 への移行

17

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

例外処理

例外はチェックされないため、以前と同じ CreateException、RemoveException、お

よび FinderException の catch 句は適用されません。

CMP クライアント・アプリケーション・コードの移行

EJB 2.x の Entity Bean を使用するアプリケーション・コードは、Entity Bean のホー

ム・インタフェースと、ローカル・インタフェースまたはリモート・インタフェー

スに密結合されています。このコードの移行が自動化される可能性はほとんどあ

りませんが、以下の方針に従うことができます。

• ホーム・インタフェースのルックアップと問合せの実行は、コンテナで

管理されていない EntityManager または Home-helper クラスを直接使用す

るように変更する必要があります。

• Entity Bean インタフェースを使用しているコードは、新しい EJB 3.0 エン

ティティを使用するように変更する必要があります。エンティティ・ク

ラスでは、インタフェース、エンティティ DTO、または新規の Entity Beanクラスのいずれかを使用できます。これらの変更の選択と挿入は、選択

した移行方式モデルにより異なります。

• エンティティのデタッチメントとアタッチメントを優先して、エンティティ

DTO のデタッチメント・コードおよびアタッチメント・コードを削除で

きます。

• ビューDTO を作成するコードは、非永続ビュー・オブジェクトを動的に

作成する EJB QL クエリーで置き換えることができます。

CMP クライアントの移行

EJB 2.x の Entity Bean は、ローカル・クライアントかリモート・クライアント、ま

たはその両方からアクセスされていました。定評のあるベスト・プラクティスで

は、Entity Bean はローカルにとどめておき、セッション・ファサードでラップす

ることが推奨されています。EJB 3.0 のエンティティは通常の Java オブジェクトで

あるため、常にローカル・オブジェクトであり、リモート(RMI)オブジェクト

になることはありません。これらは、EntityManager API を介して取得および問合

せが行われます。クライアント・コード(セッション・ファサードの場合は Session Bean)は、エンティティ・ホームの使用やコンポーネント固有のメソッドを変更

し、EntityManager を利用してエンティティにアクセスするように変更する必要が

あります。

ローカルおよびリモートのエンティティ参照は、デプロイメント・ディスクリプ

タ内での宣言が必要でした。クライアント・コードでは、JNDI を使用してホーム

をルックアップしてから、create や find などのホーム処理を実行する必要があり

ました。次に、クライアントのルックアップの例を示します。 public void createNewCustomer(String name, String city)

throws CreateException, NamingException, RemoteException {

InitialContext ctx = new InitialContext();

CustomerHome home = (CustomerHome) ctx.lookup(

"java:comp/env/ejb/CustomerHome");

CustomerLocal customer = null; customer = home.create(name, city);

EJB 3.0 への移行

18

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

}

このコードを移行すると、次のようになります。 @PersistenceContext private EntityManager em; public void createNewCustomer(String name, String city) {

Customer cust = new Customer(); cust.setName(name); cust.setCity(city); em.persist(cust);

}

以上により、EJB 2.xのEntity BeanからEJB 3.0への移行はもっとも複雑な作業で、

クライアントに影響を及ぼすため、慎重な計画が必要であることが分かります。

POJO アプリケーションの移行

一部のフレームワークでは、Java オブジェクトとリレーショナル・データベース

の関係を長期にわたって維持しており、非常に多くのアプリケーションが Oracle TopLink などの O-R フレームワークを使用して作成されています。POJO 永続化フ

レームワークを使用中のアプリケーションでは、ドメイン・オブジェクトとして

すでに Java オブジェクトを使用しているため、EJB の永続化 API への移行に適し

ています。また、永続化フレームワークのトランザクション・メカニズムおよび

セッション・レベル API は、新しい EJB の永続化 API のものに類似しています。

したがって、コードの修正は非常に少なくて済みます。現在、J2EE アプリケーショ

ンで使用する永続化フレームワークを評価している場合、Oracle TopLink などの

POJO 永続化フレームワークを使用することが最善の選択です。EJB 3.0 の永続化

API への移行が容易に実現できるからです。

新しい永続化 API へ移行するには、次の 2 つのステップが必要です。

• 永続化フレームワークで使用されているセッション API を EntityManager API に変更します。

• 専用の O-R XML から、O-R マッピング・アノテーション、または EJB 3.0の永続化 API で定義されている O-R XML に変更します。

POJO の永続性を EJB 3.0 へ移行するための技術的な詳細は、今後、別の記事で取

り上げる予定です。

結論 J2EE アプリケーションから EJB 3.0 への移行は高度な技術を要するものではあり

ませんが、その他すべての移行作業と同様に、充実した知識、リソース、計画が

求められます。プラットフォームの移行先と最終的な状態を把握することが、最

初のステップです。テクノロジを理解した後、最善の移行戦略を決定するための

計画に取りかかります。

EJB 3.0 への移行

19

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

まずアプリケーションの一部を移行してから、その手法をアプリケーション全体

に適用する方法が賢明です。この戦略を使用すると、移行における多くの困難な

問題が浮かび上がり、どの手法がアプリケーションに最適であるかを見いだすこ

とができます。この手法に従う場合、EJB 2.x と EJB 3.0 のコンポーネント間での

相互運用性などの機能が不可欠です。EJB 3.0 を早期に実装した Oracle Application Server 10g などを利用することで、EJB 3.0 の試用を開始し、EJB 3.0 への移行の準

備を整えることができます。

EJB 3.0 への移行

20

Oracle Corporation 発行「EJB 3.0 Migration」の翻訳版です。

EJB 3.0 への移行 2005 年 6 月 著者:

Debu Panda ([email protected]) Doug Clarke ([email protected]) Merrick Schincariol ([email protected])

Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065 U.S.A. 海外からのお問合せ窓口: 電話: +1.650.506.7000 ファクシミリ: +1.650.506.7200 www.oracle.com Copyright © 2003, Oracle.All rights reserved.本文書は情報提供のみを

目的として提供されており、ここに記載される内容は予告なく変更さ

れることがあります。本文書は一切間違いがないことを保証するもの

ではなく、さらに、口述による明示または法律による黙示を問わず、

特定の目的に対する商品性もしくは適合性についての黙示的な保証を

含み、いかなる他の保証や条件も提供するものではありません。オラ

クル社は本文書に関するいかなる法的責任も明確に否認し、本文書に

よって直接的または間接的に確立される契約義務はないものとします。

本文書はオラクル社の書面による許可を前もって得ることなく、いか

なる目的のためにも、電子または印刷を含むいかなる形式や手段によって

も再作成または送信することはできません。Oracle は米国 Oracle Corporation およびその子会社、関連会社の登録商標です。その他の名

称はそれぞれの会社の商標です。