S2Hibernate-JPA を使ってみる

Hibernate 上での JPA の使用を更に簡単に実施する事ができる S2Hibernate-JPA を使ってみた。

クラスパスへの設定

以下の JAR ファイルをクラスパスに設定する。

  • Seasar2 の lib ディレクトリ内の全 JAR ファイル
  • S2Tiger の lib ディレクトリ内の全 JAR ファイル
  • S2Hibernate JPA の lib ディレクトリ内の全 JAR ファイル

dicon ファイルの準備

以下のファイルをクラスパスに設定されているディレクトリにコピーする。

  • Seasar2 の resources ディレクトリ内の以下のファイル
    • convention.dicon
    • creator.dicon
    • customizer.dicon
    • jdbc.dicon
    • log4.properties
  • S2Hibernate-JPA の resources ディレクトリ内の以下のファイル
    • jpa.dicon
    • META-INF/persistence.xml

Entity や Dao の作成

JPAアノテーションを使用して Entity を作成する。

Dept.java

package aaa.entity;

import javax.persistence.*;

    @Entity
    public class Dept {

        @Id
        @GeneratedValue
        private long id;

        @Column(name = "DEPT_NO")
        private Integer deptNo;

        @Column(name = "DEPT_NAME")
        private String deptName;

        private String loc;

        //・・・アクセサメソッドの実装(記述を省略) ・・・
}

Dao のインターフェースを作成する。

DeptDao.java

package aaa.dao;

import aaa.entity.*;

public interface DeptDao {
    Dept find(long id);
    long add(String name);
}

次に、Dao の実装クラスを作成する。
通常は、サービスクラスの実装クラスに @Stateless アノテーションを付与する事になるだろうが、今回は簡単に実装するために Dao の実装クラスに @Stateless アノテーションを付ける事にした。

@Stateless アノテーションの付与により、メソッドの実行がトランザクション内で実施されるようになる。

DeptDaoImpl.java

package aaa.dao;

import javax.ejb.*;
import javax.persistence.*;

import aaa.entity.Dept;

@Stateless
public class DeptDaoImpl implements DeptDao {

    @PersistenceContext
    private EntityManager entityManager;

    public Dept find(long id) {
        return entityManager.find(Dept.class, id);
    }

    public long add(String name) {
        Dept dept = new Dept();
        dept.setDeptName(name);

        entityManager.persist(dept);
        return dept.getId();
    }
}

テスト用の実行クラス作成

Entity と Dao をテストするための実行クラスを作成する。

Seasar2 には、JUnit 用のテストクラスを作成するために org.seasar.extension.unit.S2TestCase が用意されており、通常はこのクラスを継承するクラスを作成する事でユニットテストが作成できるが、今回は普通の実行クラスでテストを実装する事にした。

Test.java

package test;

import javax.persistence.*;

import org.seasar.framework.container.*;
import org.seasar.framework.container.factory.*;

import aaa.dao.*;
import aaa.entity.*;

public class Test {
    public static void main(String[] args) {

        SingletonS2ContainerFactory.init();

        DeptDao dao = (DeptDao)SingletonS2Container.getComponent("dao");

        long id = dao.add("テストデータ");
        System.out.println(id);

        Dept dept = dao.find(id);
        System.out.println(dept.getDeptName());
    }
}

dicon ファイルの追加と編集

SingletonS2Container がデフォルトで読み込む app.dicon ファイルを「dicon ファイルの準備」のコピー先に以下のように作成する。javaee5.dicon と jpa.dicon の include は決まり事になっている模様。

app.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd">
<components>
  <include path="javaee5.dicon"/>
  <include path="jpa.dicon"/>
  <component name="dao" class="aaa.dao.DeptDaoImpl"/>
</components>

jdbc.dicon ファイルを編集し、JDBC ドライバークラスや URL の設定を行い、META-INF/persistence.xml ファイルを必要に応じて編集する。

今回は HSQLDB を使用したため、jdbc.dicon と META-INF/persistence.xml を以下のように変更した。

jdbc.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
 "http://www.seasar.org/dtd/components21.dtd">
<components namespace="jdbc">
  <include path="jta.dicon"/>
  <include path="jdbc-extension.dicon"/>
    ・・・
  <!-- for HSQLDB -->
  <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
    <property name="driverClassName">"org.hsqldb.jdbcDriver"</property>
    <property name="URL">"jdbc:hsqldb:./data/test1"</property>
    <property name="user">"sa"</property>
    <property name="password">""</property>
  </component>
    ・・・
</component>

META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
   http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
   version="1.0">
  <persistence-unit name="persistenceUnit" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/dataSource</jta-data-source>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.jndi.class" value="org.seasar.extension.j2ee.JndiContextFactory" />
      <property name="hibernate.transaction.manager_lookup_class" value="org.seasar.hibernate.jpa.transaction.SingletonTransactionManagerProxyLookup" />
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="hibernate.use_sql_comments" value="false"/>
      <property name="hibernate.hbm2ddl.auto" value="update" />
    </properties>
  </persistence-unit>
</persistence>