S2.4 & S2EJB3Unit 中村(taedium) Seasar 2.4 の特徴 1 • Sesar 2.4 は しています。 EJB 3.0 を実装 • EJB 3.0 の仕様は5月12日にFinal Releaseされたばかりの新しい技術 です。 Seasar 2.4 の特徴 2 • Sesar2.4 ではEJB 3.0に加えO/Rマッピング 機能の標準である Java Persistence API (JPA)を使うこともできます。 • Sesar2.4 でJPAを使うにはHibernateと連携 するためのS2Hibernate-JPAを利用 します。 EJB 3.0 や JPAは使える技術? • 以前のEJBに比べるとずいぶん使いやすく なっている。アノテーションを使った設定がわ かりやすい。 – EJB 3.0 : DIコンテナに慣れている人には問題な く受け入れられるはず。 – JPA : Hibernateに慣れている人には問題なく受 け入れられるはず。 • ただ… 問題点 1. EJBはサーバにデプロイしないと動かせな い。 2. EJBは単体テストがしにくい。JPAのエン ティティのデータを比較するテストが面倒。 3. EJB 3.0はインターセプタの機能が貧弱。 JPAはSQLを使いにくい。 Seasarの対応 1 • EJBはサーバにデプロイしないと動かせない。 • Seasar 2.4はサーバにデプロイし なくてもEJB 3.0のコンポーネントを動か すことを可能にする。 Seasarの対応 2 • EJBは単体テストがしにくい。JPAのエンティ ティのデータを比較するテストが面倒。 • Seasar 2.4はJUnitを拡張した S2EJB3Unitを提供し、EJB 3.0や JPAを使ったプログラムの単体テストを簡単 する。 Seasarの対応 3 • EJB 3.0はインターセプタの機能が貧弱。JPA はSQLが使いにくい。 • Seasar 2.4 は EJB 3.0の足りない機能を補 い拡張できる。 ここで簡単にまとめ ここで簡単にまとめ Sesar2.4 ではJavaの標準技術である EJB 3.0 と Java Persistence API が 使える。 さらに これらをより使いやすくする。 Sesar2.4 は Sesar 2.4でEJB 3.0を動かす • • • • • • • • • • @Stateless @EJB @Stateful @Local @TransactionManagement @TransactionAttribute @Interceptors @ExcludeClassInterceptors @PostConstruct @AroundInvoke Sesar 2.4でEJB 3.0を動かす GreetingMain GreetingClient <<realize>> GreetingClientImpl EJB 3.0を使った開発の基 本はDIコンテナを使うときと 同じ。 インタフェースに対してプロ グラミングする。 + execute() : void Greeting <<realize>> GreetingImpl + greet() : String Sesar 2.4でEJB 3.0を動かす public interface GreetingClient { void execute(); } public interface Greeting { String greet(); } 1.まず、インタフェースを作成。 @Stateless public class GreetingClientImpl implements GreetingClient { @EJB private Greeting greeting; フィールドインジェクション public void execute() { System.out.println(greeting.greet()); } } @Stateless public class GreetingImpl implements Greeting { 2.実装クラスにEJB 3.0 のアノテーションをつけ る。 3.DIするためにアノ テーションを付ける。 public String greet() { return "Hello World!"; } } 4.JNDIでlookupして実 行。 Context ctx = new InitialContext(); GreetingClient greetingClient = (GreetingClient) ctx.lookup("greetingClient"); greetingClient.execute(); S2EJB3Unitとは • JUnitの拡張版。 • EJBに対するテストを行う。 • JPAを使ったDAOのテストを行う。 • JPAのエンティティのテストを行う。 S2EJB3Unitの特徴 1 DIの指定 @EJBでDIする。 public class HogeTest extends S2EJB3TestCase { @EJB private GreetingClient greetingClient; @EJB(beanName=“xxx”) private GreetingClient greetingClient2; } S2EJB3Unitの特徴 2 DIされるコンポートの指定 public class HogeTest extends S2EJB3TestCase { @EJB private GreetingClient greetingClient; DIされるコンポーネントは 設定ファイルを使ってまと めて、もしくはクラスごとに 登録できる。 @Override public void setUp() throws Exception { super.setUp(); include("examples/ejb3/dicon/GreetingMain.dicon"); register(GreetingImpl.class); } } S2EJB3Unitの特徴 3 ロールバックをアノテーションで指定 @Rollbackでtestメソッド開始前にトランザクショ ンを開始しメソッド終了後にトランザクションをロー ルバックする。→DBを汚さずにすむ。 public class HogeTest extends S2EJB3TestCase { @Rollback public void testFindEmployee() { //…DBアクセス処理 } } S2EJB3Unitの特徴 4 EntityManagerの取得 Java Persistence APIの EntityManagerがgetterで取得 するだけで使える。 public class HogeTest extends S2EJB3TestCase { @Rollback public void testFindEmployee() { getEntityManager().find(Employee.class, new Long(1)); } } S2EJB3Unitの特徴 5 準備値(Excelデータ) 、期待値(Excelデータ)、実際値(エンティティ) テストデータはExcelで用意 してDBに書き込む。 テストの期待値はExcelで用 意する。 public class GreetingClientImplTest extends S2EJB3TestCase { @Rollback public void testFindEmployee() { readXlsWriteDb("Prepare.xls"); DataSet expected = readXls("findEmployeeResult.xls"); Employee actual = getEntityManager().find(Employee.class, new Long(1)); assertEntityEquals("0", expected, actual); } } 期待値とEntityのデータを比 較するアサートメソッド。 S2EJB3Unitの特徴 6 更新の検証 EmployeeEntityを更新。 public class GreetingClientImplTest extends S2EJB3TestCase { @Rollback public void testUpdateEmployee() { readXlsWriteDb("Prepare.xls"); DataSet expected = readXls("updateEmployeeResult.xls"); Employee employee = getEntityManager().find(Employee.class, new Long(2)); employee.setSalary(9999); assertEquals("0", expected, reload(expected)); } } DataSet同士を比較する。 DBを更新し期待値のデータを 読み直す。 S2EJB3Unitを動かしてみる • 実際にS2EJB3Unitを動かして見ます。 テーブルとエンティティのマッピング Department PK ID Employee 1 0..* PK ID FK1 FK2 EMPLOYEENAME SALALY DEPT_ID ADDRESS_ID DEPARATMENTNAME Department エンティティ Employee エンティティ 0..1 1 Address PK ID CITY Address エンティティ テーブルとエンティティの比較 1 • エンティティ単体(もしく リスト)をDBデータと比 較する ターゲットとなるエンティティ の値のみを比較する。 Employee Department PK ID PK ID FK1 FK2 EMPLOYEENAME SALALY DEPT_ID ADDRESS_ID DEPARATMENTNAME Address PK ID CITY テーブルとエンティティの比較 2 • エンティティ単体(もしく はリスト)のリレーション シップを含めてDBデー タと比較する ターゲットとなるエン ティティから辿れるリ レーションも比較対象 とする。 Employee Department PK ID PK ID FK1 FK2 EMPLOYEENAME SALALY DEPT_ID ADDRESS_ID DEPARATMENTNAME Address PK ID CITY テーブルとエンティティの比較 3 • Java上で参照があれ ば逆向きにも辿ること ができる。遅延ローディ ングにも対応。 クエリでDepartmentを取得 した場合、Employeeは遅 延ローディングされるが Employeeも比較可能。 Employee Department PK ID PK ID FK1 FK2 EMPLOYEENAME SALALY DEPT_ID ADDRESS_ID DEPARATMENTNAME Address PK ID CITY 複雑なマッピングにも対応 Department PK Employee 1 0..* ID PK ID FK1 FK2 EMPLOYEENAME SALALY DEPT_ID ADDRESS_ID DEPARATMENTNAME ポリモーフィズム を使ったマッピン グに対しても データの比較が 可能。 1 PK 0..1 FulltimeEmployee ID BONUS ID CITY 1 0..1 PK,FK1 Address 1 0..1 ParttimeEmployee PK,FK1 ID WORKHOUR エンティティの更新 • エンティティ単体(もしく リスト)をDBデータと比 較する ターゲットとなるエンティティ の値のみを比較する。 Employee Department PK ID PK ID FK1 FK2 EMPLOYEENAME SALALY DEPT_ID ADDRESS_ID DEPARATMENTNAME Address PK ID CITY
© Copyright 2024 ExpyDoc