JBoss EJB 3.0と拡張機能

  EntityManagerの基本
はじめに

EJB 3エンティティBeanは単なるPOJOなので、newキーワードを使ってそれらを生成することができます。しかしデータベースのテーブルへオブジェクトを保存したり、テーブルから取り出したりするには、EJB 3.0 EntityManagerとして知られるAPIが必要です。このトレイルでは、EntityManagerを取得する方法とその基本的な操作を学びます。

サンプルアプリケーション

このトレイルでは、前回のトレイルで説明されたデータモデルを使ってデータベース駆動の投資計算アプリケーションを実装します。次のボタンを今クリックして、いくつかの投資会社と投資家を追加してみましょう。

以下のボタンをクリックすると投資計算プログラムを起動します。ドロップダウンリストはすでに登録済みの投資会社と投資家です。"計算(calculate)"ボタンをクリックすれば、アプリケーションは投資会社と投資家の詳細情報(例えば、投資成長率、投資家の開始年齢と終了年齢)を取り出し、その情報を使って計算を実行します。

EntityManagerの取得

計算アプリケーションの初期の段階(iteration)では、CalculatorBeanセッションBeanはすべてのビジネスロジックを扱い、クライアント(すなわち、サーブレット)にインタフェースを提供します。そこで、すべてのエンティティBean操作はCalculatorBeanクラス内部でおこなわれます。EntityManagerオブジェクトは@PersistenceContextアノテーションを使ってCalculatorBean注入(inject)することが可能です。これは明示的なEntityManagerオブジェクトの生成や(訳注:JNDIから)ルックアップが必要がないことを意味します。その値はそれを使うときになってEJB 3.0コンテナによって自動的に割り付けられるのです


@Stateless
public class CalculatorBean implements Calculator {

  @PersistenceContext // (unitName="ejb3trail")
  protected EntityManager em;
  
  // ... ...
}

注意: アプリケーションが複数のEntityManagerを持ち、それぞれが異なるデータベース設定を持つ場合に、@PersistenceContextアノテーションのunitName属性はコンテナにどのEntityManagerオブジェクトが注入されるのかを示します。このトピックに関する詳細は、ハイキングの後半に登場する"Persitence Contextの構成 (Configure Persistence Context)"のトレイルを参照してください。

エンティティBeanオブジェクトの永続化

EntityManager.persist()メソッドは新しい行としてデータベースのテーブルにエンティティBeanインスタンスを保存します。以下のコードはエンティティBeanの作成、属性の設定、そして次にそれをデータベースに保存する方法を示します。


@Stateless
public class EntityCalculator implements Calculator {

  @PersistenceContext
  protected EntityManager em;

  public void addFund (String name, double growthrate) {
    Fund fund = new Fund (name, growthrate);
    em.persist (fund);
  }

  public void addInvestor (String name, int start, int end) {
    Investor investor = new Investor (name, start, end);
    em.persist (investor);
  }

  // ... ...
}
エンティティBeanの取得

エンティティBean POJOをデータベースに保存するということは、永続化処理の半分の操作に過ぎません。アプリケーションがデータを使う必要があるときには、データベースからそれを取得する必要があるでしょう。EntityManager.find()メソッドは、エンティティBeanクラス名(すなわち、データベースのテーブル名)とエンティティID(すなわち、データベースの主キー)を使ってデータベースからエンティティBeanインスタンスを取得します。O/Rマッピングのスキーマでは、エンティティIDはエンティティBeanインスタンスのId属性です。次のCalculatorBeanのコード片はEntityManager.find()の使い方を示します。


@Stateless
public class EntityCalculator implements Calculator {

  @PersistenceContext
  protected EntityManager em;
  
  // ... ...
  
  public double calculate (int fundId, int investorId, double saving) {

    Investor investor = 
        em.find(Investor.class, 
                Integer.valueOf(investorId));
    Fund fund = 
        em.find(Fund.class, 
                Integer.valueOf(fundId));

    int start = investor.getStartAge();
    int end = investor.getEndAge();
    double growthrate = fund.getGrowthrate();

    // ... ...

    TimedRecord rec = 
        new TimedRecord (fund, investor, saving, result, ts);
    em.persist (rec);

    return result;
  }

}

主キーIDに基づいたエンティティBeanの検索と取得は簡単です。しかし、探しているデータの主キーIDを知っているとは限らないのが問題です。このトレイルでは、しばらくの間は、主キーや名前を使ってデータベースからFundInvestorエンティティBeanのリストを取得する方法は無視してきました。これは次のトレイルで扱いましょう。

ソースコード参照

セッションBeanはデータベースからFundInvestor Beanの永続化や取得をします。

CalculatorBeanクラスのgetFunds()getInvestors()は今のところ気にしないでください。それらについてはEJB問合せ言語(EJB query language)を調べるトレイルの後半で議論します。

JSPユーザインタフェース

まとめ

このトレイルでは、エンティティBeanを作成、保存、取得する方法について学びました。データベースのキーとなる機能は問合せ言語を使ってデータベースを検索、取得可能なことで、これによって特定のテーブル(すなわち、私たちのアプリケーションでのFundInvestorテーブル)のすべての行を取得できるようになります。EntityManagerは先進的なデータベース問合せをサポートします。次のトレイルでこれについて調べていきましょう。