EJB 3.0(Public Draft)入門記 Java Persistence API Embeddable EJB 3.0へのりかえ

今までJBoss Application Serve 4.0.3 R1 + JBoss EJB3 R1を使ってきましたが、デプロイがあまりに面倒くさいのでJBossのEmbeddable EJB3というものを使ってみたいと思います。VersionはAlphaです。Embeddable EJB3はアプリサーバ外で動作可能なんだそうです。仕組みはよくわかっていないのですが、デプロイしなくてもPersistence APIがいろいろ試せるならこっちのほうがいいですね。

まずhttp://www.jboss.com/products/list/downloads#ejb3からEmbeddable EJB3をダウンロードします。
ドキュメントを読むとalpha版の制限などがかいてありますが、Persistence APIの動作を確かめるために使うには特にもんだいなさそう。TutorialにはEmbeddable EJB3の使う方法はいろいろあるのですが、microcontainer-deploymentとという方法がほかのものとくらべて一番簡単そうです。

Eclipseに環境を設定します。

  • ダウンロードしたzipファイルに入っているEmbeddable EJB3のjarをビルドパスに通します。jarファイルはなんと64個。すげー。
  • ダウンロードしたzipファイルに入っているconfフォルダをエクリプスにコピーしてクラスパスに通します。
  • サンプルについているresourceフォルダをエクリプスにコピーしクラスパスに通します。persistence.xmlが入っているはず。persistence.xmlJava Persistence API標準の設定ファイルです。
  • microcontainer-deploymentのサンプルのconfフォルダ下のejb3-deployment.xmlをエクリプス上に作成したconfファイルにコピーします。ejb3-deployment.xmlJBossの設定ファイルでマイクロカーネルとかいうものに関連した設定ファイルのようです。
  • confフォルダ下のembedded-jboss-beans.xmlファイルにデータソースを設定する箇所があるのですが、HSQLDBのDatabaseManagerからアクセスできるようにconnectionURLを「jdbc:hsqldb:hsql://localhost:1701」と書き換えてみました(デフォルトのままでも問題なかったのかもしれないですが)。ちなみになぜかorg.hsqldb.util.DatabaseManagerが使えなかったのでorg.hsqldb.util.DatabaseManagerSwingを使うことにしました。
  • persistence.xmlはちょっとだけ書き換えときます。プログラム実行時にDBスキーマの作成を毎回行わないようにhibernate.hbm2ddl.autoのvalueをcreate-dropからupdateに変更します。SQLのログを標準出力へ吐かせるためにを追加します。
<?xml version="1.0" encoding="UTF-8"?>
<entity-manager>
   <name>custdb</name>
   <jta-data-source>java:/DefaultDS</jta-data-source>
  <properties>
    <property name="hibernate.dialect"
      value="org.hibernate.dialect.HSQLDialect"/>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
    <property name="hibernate.show_sql" value="true"/>
  </properties>
</entity-manager>
  • jndi.propertiesをクラスパスに通します。jndi.propertiesの中身は次のとおりです。confフォルダ下のembedded-jboss-beans.xmlのなかですでにJNDIの設定があるのにここで同じように設定するのはどうかなと思うのですが、embedded-jboss-beans.xmlがどこで使われているのかわからないし、jndi.propertiesを用意するかプログラム中で明示的にプロパティを渡すかしないとうまく動かないということでjndi.propertiesを使うことにしました。
java.naming.factory.initial=org.jnp.interfaces.LocalOnlyContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces


前回使用したSessionBeanというクラスにmainメソッドを持たせて実行してみます。クラス名もメソッド名もややこしくてすみません。

@Stateless
public class SessionBean implements Session {

  @PersistenceContext
  private EntityManager em;

  public void main() {

    // Departmentからたどる
    Department department = em.find(Department.class, 1);
    System.out.println("--Department--");
    System.out.println(department.getName());
    System.out.println("--Employee--");
    for (Employee e : department.getEmployees()) {
      System.out.println(e.getName());
    }

    // Employeeからたどる
    Employee employee = em.find(Employee.class, 1);
    System.out.println("--Employee--");
    System.out.println(employee.getName());
    System.out.println("--Department--");
    System.out.println(employee.getDepartment().getName());
  }

  public static void main(String[] args) throws Exception {
    EJB3StandaloneBootstrap.boot(null);
    EJB3StandaloneBootstrap.deployXmlResource("ejb3-deployment.xml");

    InitialContext ctx = new InitialContext();
    Session s = (Session) ctx.lookup(Session.class.getName());
    s.main();
    
    EJB3StandaloneBootstrap.shutdown();    
  }
}

特別なことは次のようにEJB3StandaloneBootstrapというクラスのメソッドを呼んでいることです。

    EJB3StandaloneBootstrap.boot(null);
    EJB3StandaloneBootstrap.deployXmlResource("ejb3-deployment.xml");
    // ...
    EJB3StandaloneBootstrap.shutdown();

チュートリアルではEJB3StandaloneBootstrap.shutdown()は呼ばれていなかったのですが呼んどいたほうがいいかなとおもってつけときました。使い方あってるか確認してないです。あと前回からの変更点としては@Remoteはずしました。@Statelessは必要みたいです。


上記クラスを実行するとhbm2ddlが実行されてテーブルが作成されるのですが、まだデータがありません。前回と同じデータをHSQLDBのDatabaseManagerから作成して再度実行します。

 Hibernate: select department0_.id as id1_0_, department0_.name as name1_0_ from Department department0_ where department0_.id=?
 --Department--
 第1システム部
 --Employee--
 Hibernate: select employees0_.department_id as department3_1_, employees0_.id as id1_, employees0_.id as id2_0_, 
 employees0_.name as name2_0_, employees0_.department_id as department3_2_0_ from Employee employees0_ where employees0_.department_id=?
 ゴン
 うさはな
 タクヤ

 --Employee--
 ゴン
 --Department--
 第1システム部

前回と同じ結果になってちゃんとPersistence APIが動いている模様です。ついでに実行されたSQLも表示されました。デプロイするよりこっちのほうがはるかに楽チンです。


次回からはEmbeddable EJB3を使って入門記を続けたいとおもいます。