エンティティ・マネージャは、EJB 3.0永続性フレームワークによって提供されるエンティティ管理サービスへのクライアント・ゲートウェイです。 エンティティ・マネージャは、既存のエンティティ・インスタンスの問合せ、更新、リフレッシュ、削除、および新規永続オブジェクトを作成するエンティティ・クラスのIDへの登録をサポートしています。
また、エンティティ・マネージャは、永続性コンテキストと呼ばれるトランザクション・コンテキスト内に、インスタンスのキャッシュを保持します。 永続性コンテキストによって、エンティティ・マネージャは、変更、作成、削除されたエンティティ・インスタンスをトラッキングし、エンティティ・マネージャ自体のトランザクションと同時に外部トランザクションによってコミットされた変更内容でエンティティ・インスタンスを調整します。
エンティティ・マネージャを介して問合せが実行されるエンティティ・インスタンスは、EJBコンテナの内部と外部両方のクライアントに自由に渡すことができます。 クライアントは、通常のJavaオブジェクトの場合と同様に、エンティティ・データにアクセスし、更新できます。
EntityManagerインスタンスは、EJBコンテナの内部(Java EE)および外部(Java SE)の両方から取得できます。 この結果、クライアントは、永続性コードがEEコンテナの内部と外部のいずれで実行されているかに関係なく、一般的な方法で永続エンティティBeanと柔軟に対話できます。
クライアント・セッションでは、永続エンティティ・インスタンスと対話する前に、EntityManagerインスタンスを取得する必要があります。 ほとんどの場合、EntityManagerのインスタンスを挿入する方法をお薦めします。 ただし、より正確に制御するためにEntityManagerFactoryを使用したり、JNDI参照を使用する必要がある場合があります。
例4-5では、Customerエンティティを含む永続性ユニットにバインドされているEntityManagerインスタンスを取得するために、コンテナ・インジェクションが使用されています。 この場合、新規Customerインスタンスの永続化にEntityManagerが使用されます。
コンテナ・インジェクションが使用できない場合、またはEntityManagerのライフサイクルをより詳細に制御する必要がある場合、クライアントは、最初にEntityManagerFactoryを取得することによってEntityManagerを取得できます。 javax.persistence.Persistenceクラスが、EntityManagerFactoryを取得するためのファクトリとして機能します。 例4-6に、Java SEサービス・クライアントによるEntityManagerの取得方法を示します。 この例では、EntityManagerFactoryが作成され、Customerエンティティを含む永続性ユニットにバインドされます。 次に、このファクトリからEntityManagerインスタンスが作成され、新規Customerインスタンスの永続化に使用されます。
例4-6 EntityManagerFactoryを使用したJavaサービス・ファサード
public class CustomerService { public static void main(String[] args) { final EntityManagerFactory emf = Persistence.createEntityManagerFactory("customerServiceUnit"); final EntityManager em = emf.createEntityManager(); final Customer cust = new Customer(); cust.setName("New Customer"); em.persist(cust); } }
使用可能なもう1つのオプションは、JNDIを使用してEntityManagerFactory、またはEntityManager自体を検索することです。 例4-7に、この検索がセッションBean内からどのように実行されるかを示します。
名前付き問合せを作成するには、EJB QL構文を使用して、エンティティ・クラスで問合せを直接入力します。 @NamedQueriesを使用してEJB QL問合せのグループを示し、@NamedQueryを使用して各EJB QL問合せを示します。
例4-8では、findAllCustomer、findCustomerByIdおよびfindCustomerByEmailの3つの名前付き問合せが定義されています。 最初のfind-allメソッドは、エンティティの作成時にデフォルトで生成されます。 他の2つの名前付き問合せは、ソース・コードに注釈を付けることによって作成されています。
例4-8 名前付き問合せ
@NamedQueries({ @NamedQuery(name="Customer.findAll", query="select object(o) from Customer o"), @NamedQuery(name="Customer.findById",query="select object(cust) from Customer cust where cust.custid = :custid"), @NamedQuery(name="Customer.findByEmail",query="select object(cust) from Customer cust where cust.email = :email and cust.password = :password") })
セッションBeanを作成または編集する場合は、セッション・ファサードを介して公開するメソッドを選択できます。 第4.4.4項「新規エンティティを使用した既存セッションBeanの更新方法」を参照してください。
戻されるオブジェクトがリストまたはコレクションの場合は、フレームワークによって正しい戻り型が判断されますが、単一オブジェクトの場合は、戻り型を指定する必要があります。 次の第4.5.3.1項「単一値を戻すメソッドの戻り型の変更方法」を参照してください。
メソッドの戻り型の変更は、2段階のプロセスです。最初に「Beanメソッドの詳細」ダイアログで戻り型を変更し、次にソース・コードを変更します。
「Beanメソッドの詳細」ダイアログを開くには、図4-7に示すように、「構造」ペインで、セッション・ファサードで生成するメソッドを選択し、右クリックして「プロパティ」を選択します。
「Beanメソッドの詳細」ダイアログで、適切なオブジェクト型が戻されるように戻り型を変更します。 たとえば、SOA Order Bookingアプリケーションでは、図4-8に示すように、findCustomerByIdメソッドによって、org.soademo.customerservice.persistenceパッケージにあるCustomerのインスタンスが戻されます。
ヒント: 戻り型を手動で入力すると、エラーが発生する可能性があります。 ネイティブJava型の1つを使用している場合は、ドロップダウン・リストを使用して適切な戻り型を選択してください。 戻り型がクラスの場合は、「Beanメソッドの詳細」ダイアログの「参照」ボタンを使用して、ワークスペース内の適切なオブジェクトを検索してください。 |
メソッドの戻り型を変更した後は、ソース・コードも変更する必要があります。 例4-9に示すように、最初に、オブジェクトを正しい型にキャストした後で、getResultList()をgetSingleResult()に変更します。