Seasar DI Container with AOP

このドキュメントはS2Hibernateのバージョン1.1.2のものです。
S2Hibernate1.1.2はSeasar2のバージョン2.3.4以降に対応しています。2.3.3以前では動作しないのでご注意ください。
Seasar2のバージョン2.2.7〜2.3.3と組み合わせる場合はS2Hibernate1.1.1をお使いください。
S2Hibernate1.1.2はHibernate 2.1.8とHibernate 3.1.1でテストし、これらをバンドルしています。

S2Hibernateの概要

S2Hibernateは以下の特徴を持っています。

  • S2のJTAやConnectionPoolとHibernateが簡単に連動するようになります。
  • これまでHibernateで開発するときの悩みの種だったSession管理をS2Hibernateが自動的に行ってくれるので、 開発者はSessionのオープン・クローズ、Transaction処理から開放されます。 SessionはJTAのトランザクション中は維持され、トランザクションの終了時に自動的にクローズ(flushも)されます。

  • HibernateのSessionを意識しないで記述できる
  • S2Hibernate.daoを使うことで、HibernateのSessionを意識せずにDaoを記述できるようになります。
    S2hibernate.daoでは定数アノテーションという技術を使い、ソースコードにメタデータを記述するだけで動作するようになります。
    定数アノテーションとHQL文だけを書けば、動作するようになるので開発効率が向上します。

S2Hibernateリファレンス

セットアップ

  • Eclipseへのインポート
  • S2と同様にJDK1.4以上が必要です。
    あらかじめSeasar2をダウンロードして、EclipseのJavaプロジェクトとしてワークスペースにインポートしてください。
    S2Hibernate-Vx.x.x.zipを解凍してできたs2hibernateディレクトリをEclipseのJavaプロジェクトとしてワークスペースにインポートしてください。

  • 必要なjarファイル
  • S2Hibernateとして必要なjarファイルは、s2hibernate/lib以下にそろってます。この他にSeasar2のjarファイルが必要です。
    s2hibernate/lib直下にはHibernate 2およびHibernate 3のどちらを使う場合でも必要なjarファイルがあります。
    Hibernate 2を使う場合に必要なjarファイルはs2hibernate/lib/hibernate2、Hibernate 3を使う場合に必要なjarファイルはs2hibernate/lib/hibernate3以下にあります。
    利用するHibernateのバージョンに合わせて選択してください。
    Hibernateはコネクションプールやキャッシュの実装をいろいろ選べるようになっているので、S2Hibernateで用意していない実装が必要な場合は、Hibernateのサイトよりダウンロードしてください。

  • クラスパス
  • libのjarファイル(hsqldb.jarは必要に応じて)とlib/hibernate2またはlib/hibernate3のjarファイル、srcのhibernate.cfg.xml、ehcache.xml、j2ee.dicon、log4j.propertiesをCLASSPATHにとおせば、S2Hibernateを実行できます。Eclipseにインポートして使う場合は設定は不要です。

  • データベース
  • 簡単に機能を試すことができるように、RDBMSとしてHSQLDBを用意しています。機能を試す前にあらかじめHSQLDBを実行しておいてください。HSQLDBを実行するには、bin/runHsqldb.batをダブルクリック(Windowsの場合)します。lib/hsqldb.jarはHSQLDBを実行する上では必要ですが、本番では必要ありません。

Hibernateのバージョン

s2hibernateV1.1.0からHibernate3に対応しました。
しかし、現在のドキュメントは、Hibernate2を対象に記述していますので、 Hibernate3を利用する場合は、次のように読み替えてください。
 Hibernate2Hibernate3
S2SessionFactoryImplorg.seasar.hibernate.S2SessionFactoryorg.seasar.hibernate3.S2SessionFactory
S2Sessionorg.seasar.hibernate.S2Sessionorg.hibernate.Session
設定ファイルhibernate.cfg.xmlhibernate3.cfg.xml
マッピングファイルEmployee.hbm.xml
Department.hbm.xml
Employee3.hbm.xml
Department3.hbm.xml
diconファイルs2hibernate.dicons2hibernate3.dicon

基本的な使い方

S2Hibernateの機能を使用するにあたり、JavaBeans、Dao(.java)、diconファイルの作成が必要になります。

JavaBeans

通常のJavaBeanを作成します。S2Hibernateを意識する必要はありませが、Hibernateで利用できるように記述してください。

Dao(Data Access Object)

例)Dao実装(EmployeeDaoImpl.java)

  1. S2SessionFactory型のフィールドを定義。
    private S2SessionFactory sessionFactory_;
  2. コンストラクタあるいはプロパティ経由で実装クラス(S2SessionFactoryImpl)を受け取るように記述。
    public EmployeeDaoImpl(S2SessionFactory sessionFactory) { 
    	sessionFactory_ = sessionFactory;
    }
  3. 各メソッドでS2SessionFactoryからS2Sessionを取得し、処理を記述する。
  4. public Employee getEmployee(int empno) {
        List result = sessionFactory_.getSession().find(
            HQL, new Integer(empno), Hibernate.INTEGER);
        if (result.size() > 0) {
            return (Employee) result.get(0);
        } else {
            return null;
        }
    }
    • Sessionのオープン・クローズ、トランザクション制御は必要ありません。
    • S2SessionFactory.getSession()が返すオブジェクトは、HibernateのSessionのラッパーであるS2Sessionです。
      実行できるメソッドはHibernateのSessionと同じで、検査例外(HibernateException)を実行時例外(HibernateRuntimeException)に変換してくれます。
      そのため、HibernateExceptionをcatchしたくないクラスは特に何もする必要はありません。 catchする必要がある場合は、HibernateRuntimeExceptionでcatchしてgetCause()でHibernateExceptionを取り出します。

diconファイル

作成したDaoクラスとorg.seasar.hibernate.impl.S2SessionFactoryImplを追加します。
例)Employee.dicon


S2Hibernate.daoの使い方

S2hibernate.daoを使うと、Sessionを意識せずにDaoを記述することができます。
S2hibernate.daoでは定数アノテーションという技術を使い、ソースコードにメタデータを記述するだけで動作するようになります。
定数アノテーションとHQL文だけを書けば、動作するようになるので開発効率が向上します。

S2Hibernate.daoの機能を使用するにあたり、JavaBeans、Dao(.java)、diconファイルの作成が必要になります。

JavaBeans

通常のJavaBeanを作成します。S2Hibernateを意識する必要はありませが、Hibernateで利用できるように記述してください。

Dao(Data Access Object)

S2hibernate.daoでは定数アノテーションという技術を使い、ソースコードにメタデータを記述するだけで動作するようになります。

BEANアノテーション

Dao(Data Access Object)がどのJavaBeans(エンティティ)に関連付けられているのかはBEANアノテーションで指定します。 例えば、EmployeeDaoクラスがEmployeeエンティティに関連付けられる場合は次のように定義します。

public static final Class BEAN = Employee.class;
HQLアノテーション

HQLアノテーションを使って、HQL文を指定して実行することができます。

public String getEmployeeByEname_ARGS = "employeeName";
public String getEmployeeByEname_HQL = "from Employee emp where emp.ename = :employeeName";
public List getEmployeeByEname(String employeeName);

ARGSアノテーションに合わせて、HQLに値を渡していきます。

NamedQueryを使う場合
Hibernateのマッピングファイルに記述したNamedQueryのname属性を次の様に指定します。
  [Daoインターフェース名]+"_"+[メソッド名]
例)examples.hibernate.dao.EmployeeAutoDaoクラスのgetSQLEmployeeNameByIdメソッドで使うNamedQueryを指定する場合
<query name="examples.hibernate.dao.EmployeeAutoDao_getSQLEmployeeNameById"><![CDATA[
    select emp.ename from Employee emp where emp.empno = :employeeId
]]></query>
ARGSアノテーション

メソッドの引数名をARGSアノテーションを使って指定します。メソッドの引数名は、リフレクションで取得できないためです。

public static final String getEmployee_ARGS = "empno";
public Employee getEmployee(int empno)

引数が複数ある場合には、カンマで区切ります。

※予約語
  HQLアノテーション又は、NamedQueryを利用した検索を行う場合、ARGSアノテーションで次の2つが予約語なります。
    "firstResult":検索結果の何レコード目から取得するか。
    "maxResults":検索結果から、何件取得するか。

public String getEmployeeList_ARGS = "MaxResults";
public String getEmployeeList_HQL = "from Employee emp order by emp.empno";
public List getEmployeeList(int MaxResults);
ARGSアノテーションを使っての検索の自動処理T
S2hibernate.daoに自動的に検索処理を生成させることもできます。HQLアノテーションを指定せず、ARGSアノテーションを指定することで自動的に処理されます。 必要なのは次の定義だけです。

public static final String getEmployeeByJobDeptno_ARGS = "job, deptno";
public List getEmployeeByJobDeptno(String job, Integer deptno);	
上の例の場合、次のHQL文として扱い":job",":empno"の部分に引数の値を渡します。
from Employee emp where emp.job = :job and emp.deptno = :deptno

S2hibernate.daoでは、引数がNullの場合、検索条件に含めません。この例で、deptnoがNullの場合の次の様なHQLに相当する処理を生成します

from Employee emp where emp.job = :job
ARGSアノテーションを使っての検索の自動処理U
「ARGSアノテーションを使っての検索の自動処理T」の自動処理がイコール("=")限定だったのに対して、 ARGSアノテーションの引数名の後ろに比較演算子を追加することで、指定した比較演算子を使っての比較が出来ます。

※利用できる演算子 : = ,> ,>= ,< ,<= ,like ,in

//ARGSアノテーションに比較オペレーター(>)を指定した場合
public String getEmployeeByGtSal_ARGS = "sal >";
public List   getEmployeeByGtSal( BigDecimal sal );
上の例の場合、次のHQL文として扱い":sal"に引数の値を渡します。
from Employee emp where emp.sal > :sal 
「ARGSアノテーションを使っての検索の自動処理T」と同様、引数がNullの場合、検索条件に含めません。
DTO(Data Transter Object)を使う場合
メソッドの引数にDTO(Data Transter Object)を使う場合、ARGSアノテーションせず、メソッドの引数をDTO1つにします。 HQL(HQLアノテーションまたは、NamedQuery)にDTOの値を渡す場合、 HQLの中の名前付き引数(変数名に":"つける)とDTOのプロパティ名をあわせることで、 メソッドの実行時に、HQLにDTOの値が渡されて実行されます。
DTO(Data Transter Object)を使って自動処理する場合T
HQL(HQLアノテーションまたは、NamedQuery)が指定されていないメソッドに対して、DTO利用した場合、DTOのプロパティ名から自動的に検索処理を行います。 イメージとしては、HibernteのExampleの様な機能になります。
渡されてたDTOのNullでないプロパティを検索条件にして、オブジェクトを検索します。
(nullでないもを検索条件にするので、プリミティブ型は想定していません。)
DTO(Data Transter Object)を使って自動処理する場合U
「DTO(Data Transter Object)を使って自動処理する場合T」の自動処理がイコール("=")限定だったのに対して、 PROPERTYアノテーションを指定することで、比較演算子を使っての比較が出来ます。
PROPERTYアノテーション
PROPERTYアノテーションは、DTOを使う場合のみに指定します。 記述する内容はARGSアノテーションにDTOのプロパティ名を追加した形式になります。
形式:[エンティティのプロパティ名]+" "+[演算子]+" "+[DTOのプロパティ名]
	//ARGSアノテーションに比較オペレーター(>=,<=)を指定した場合(EmployeeSearchDto)
	//指定したフィールドが指定した範囲の値のオブジェクトを取得したいとき
	public String getEmployeeByDto_PROPERTY = "empno,ename,job,mgr,deptno," +
		"hiredate >= fromHiredate,hiredate <= toHiredate,sal >= fromSal,sal <= toSal";
	public List   getEmployeeByDto( EmployeeSearchDto dto );

この例の場合、
"empno,ename,job,mgr,deptno"の部分に関しては、エンティティとDTOのプロパティ名が一致しているため、DTOのプロパティ名の記述が省略されています。また、演算子も=(イコール)を使うので省略されています。 次の3つはどれを記述しても同じ意味になります。
 "empno,ename,job,mgr,deptno"
 "empno =,ename =,job =,mgr =,deptno ="
 "empno = empno,ename = ename,job = job,mgr = mgr,deptno = deptno"

"hiredate >= fromHiredate,hiredate <= toHiredate,sal >= fromSal,sal <= toSal"の部分に関しては、
BEANアノテーションに記述されているEmployeeクラスのhiredateプロパティが
DTOのfromHiredateプロパティの値以下であるという様な条件が4パターン記述されていることになります。
メソッドの定義

S2Hibernate.daoではメソッドのsignatureより処理を自動的に決定しています。 そのためメソッドのsignatureはS2hibetnate.daoの想定にあわせてもらう必要があります。

処理 メソッド名 備考
save insert,create,add,save
ではじまる
戻り値はvoidです。
引数の型はエンティティの型と一致させます。
update merge,update
ではじまる
戻り値はvoidです。
引数の型はエンティティの型と一致させます。
※ Hibernateのupdateは永続オブジェクトをHibernateのSessionに関連づけるメソッドです。
saveOrUpdate saveOrUpdateではじまる 戻り値はvoidです。
引数の型はエンティティの型と一致させます。
load loadではじまる 戻り値はObjectです。
引数の型は主キーカラム(id)の型と一致させます。
delete delete,removeではじまる 戻り値はvoidです。
引数の型はエンティティの型と一致させます。
select 上記に該当しない場合 ・戻り値の型がjava.util.Listを実装している場合、検索結果のエンティティのリストを返します。
・戻り値の型がエンティティの型の場合、エンティティを返します。
・それ以外の場合、select count(emp) from Employee empのように1行で1のカラムの値を返すというようにS2Hibernate.daoは想定します。

※select時に実行するHQL文の優先順位

  1. HQLアノテーションを指定している場合、HQLアノテーションに記述したHQL文を実行します。
  2. Hibernateのマッピングファイルに[ Daoインターフェース名 + "_" +メソッド名 ] でNamedQueryが指定されていた場合、その指定されているクエリーを実行します。
  3. Hibernateのマッピングファイルに[ メソッド名 ] でNamedQueryが指定されていた場合、その指定されているクエリーを実行します。
  4. 上記に当てはまらない場合、ARGSアノテーションまたは、PROPERTYアノテーションを使って自動処理を行います。
  5. ARGSアノテーション、PROPERTYアノテーションの指定がない場合、BEANアノテーションで指定したエンティティすべてを含んだListを返します。

diconファイル

作成したDaoクラスを追加します。
s2hinernate.diconを追加します。
例)EmployeeAutoDao.dicon
  s2hibernate.dicon


Example

基本的な使い方の例

作成するファイは以下のとおりです。

Employee.java

通常のJavaBeanを作成します。S2Hibernateを意識する必要はありませがHibernateで利用できるように記述してください。
package examples.hibernate.entity;

import java.io.Serializable;

public class Employee implements Serializable {

    private long empno;
    private String ename;
    private String job;
    private Short mgr;
    private java.util.Date hiredate;
    private Float sal;
    private Float comm;
    private short deptno;

    public Employee() {}
    public Employee(long empno) { this.empno = empno; }

    public long getEmpno() { return this.empno; }
    public void setEmpno(long empno) { this.empno = empno; }

    public java.lang.String getEname() { return this.ename; }
    public void setEname(java.lang.String ename) { this.ename = ename; }

    public java.lang.String getJob() { return this.job; }
    public void setJob(java.lang.String job) { this.job = job; }

    public Short getMgr() { return this.mgr; }
    public void setMgr(Short mgr) { this.mgr = mgr; }

    public java.util.Date getHiredate() { return this.hiredate; }
    public void setHiredate(java.util.Date hiredate) { this.hiredate = hiredate; }

    public Float getSal() { return this.sal; }
    public void setSal(Float sal) { this.sal = sal; }

    public Float getComm() { return this.comm; }
    public void setComm(Float comm) { this.comm = comm;}

    public short getDeptno() { return this.deptno; }
    public void setDeptno(short deptno) { this.deptno = deptno; }

    public boolean equals(Object other) {
        if ( !(other instanceof Employee) ) return false;
        Employee castOther = (Employee) other;
        return this.getEmpno() == castOther.getEmpno();
    }

    public int hashCode() {
        return (int) this.getEmpno();
    }
}

Employee.hbm.xml

通常のHibernateのマッピングファイルを作成します。S2Hibernateを意識する必要はありません。
<hibernate-mapping>
<class name="examples.hibernate.entity.Employee" table="EMP">
<id name="empno" column="EMPNO" type="long">
<generator class="assigned"/>
</id>
<property name="ename" column="ENAME" type="string" length="10"/>
<property name="job" column="JOB" type="string" length="9"/>
<property name="mgr" column="MGR" type="short" length="4"/>
<property name="hiredate" column="HIREDATE" type="timestamp"/>
<property name="sal" column="SAL" type="float" length="7"/>
<property name="comm" column="COMM" type="float" length="7"/>
<property name="deptno" column="DEPTNO" type="short" length="2"/>
</class>
</hibernate-mapping>

EmployeeDao.java

Dao用のインターフェースを宣言します。S2Hibernateを意識する必要はありません。
package examples.hibernate.dao;

import examples.hibernate.entity.Employee;

public interface EmployeeDao {

    public Employee getEmployee(int empno);
}

EmployeeDaoImpl.java

Dao用の実装を記述します。

  1. S2SessionFactory型のフィールドを定義
  2. コンストラクタで、S2SessionFactoryを取得するように記述
  3. 各メソッドでS2SessionFactoryからS2Sessionを取得し、処理を記述する
package examples.hibernate.dao;

import java.util.List;
import net.sf.hibernate.Hibernate;
import org.seasar.hibernate.S2SessionFactory;
import examples.hibernate.entity.Employee;

public class EmployeeDaoImpl implements EmployeeDao {

    private static final String HQL = "from Employee where empno = ?";
    private S2SessionFactory sessionFactory_;

    public EmployeeDaoImpl(S2SessionFactory sessionFactory) {
        sessionFactory_ = sessionFactory;
    }

    public Employee getEmployee(int empno) {
        List result = sessionFactory_.getSession().find(
            HQL, new Integer(empno), Hibernate.INTEGER);
        if (result.size() > 0) {
            return (Employee) result.get(0);
        } else {
            return null;
        }
    }
}

Employee.dicon

作成したDaoクラスとorg.seasar.hibernate.impl.S2SessionFactoryImplを追加します。

<components>
<include path="j2ee.dicon"/>
<component class="org.seasar.hibernate.impl.S2SessionFactoryImpl"/>
<component class="examples.hibernate.dao.EmployeeDaoImpl">
<aspect>j2ee.requiredTx</aspect>
</component>
</components>

EmployeeClient.java

Daoを実行する基本的な方法は以下のようになります。

  1. 作成したdiconファイルのパスを引数にS2Containerを生成
  2. 生成したS2ContainerからgetComponentを呼び出し、登録したDaoを取得する
  3. 取得したDaoのメソッドを実行する

S2Hibernateではトランザクション制御は行なっていません、トランザクションについてはトランザクションの自動制御を参照して下さい。

実行クラスサンプル
package examples.hibernate.client;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

import examples.hibernate.service.EmployeeService;

public class EmployeeClient {

    private static final String PATH =
        "examples/hibernate/client/Employee.dicon";

    public static void main(String[] args) {
        S2Container container = S2ContainerFactory.create(PATH);/* 手順1 */
        container.init();
        try {
            EmployeeService service =
                (EmployeeService) container.getComponent(EmployeeService.class);/* 手順2 */
            System.out.println(service.getEmployee(7788).getEname());/* 手順3 */
        } finally {
            container.destroy();
        }

    }
}

実行結果

DEBUG 2004-04-07 18:53:52,511 [main] トランザクションを開始しました
2004/04/07 18:53:52 net.sf.hibernate.cfg.Environment <clinit>
情報: Hibernate 2.1.2
省略 DEBUG 2004-04-07 18:53:54,654 [main] 物理的なコネクションを取得しました
DEBUG 2004-04-07 18:53:54,744 [main] 論理的なコネクションを取得しました
Hibernate: select employee0_.EMPNO as EMPNO, employee0_.ENAME as ENAME, employee0_.JOB as JOB, employee0_.MGR as MGR, employee0_.HIREDATE as HIREDATE, employee0_.SAL as SAL, employee0_.COMM as COMM, employee0_.DEPTNO as DEPTNO from EMP employee0_ where (empno=? )
DEBUG 2004-04-07 18:53:55,605 [main] 論理的なコネクションを閉じました
DEBUG 2004-04-07 18:53:55,625 [main] トランザクションをコミットしました
SCOTT
DEBUG 2004-04-07 18:53:55,625 [main] 物理的なコネクションを閉じました

S2hibernate.daoの使い方の例

EmployeeAutoDao

package examples.hibernate.dao;

import java.util.List;
import examples.hibernate.entity.Employee;

public interface EmployeeAutoDao {

	public Class BEAN = Employee.class;

	//追加、削除、更新、保存or更新をする場合
	public void save(Employee employee);
	public void delete(Employee employee);
	public void update(Employee employee);
	public void saveOrUpdate(Employee employee);
	
	//HQLを指定しないで実行する場合
	public String getEmployeeByEmpNo_ARGS = "empno";
	public Employee getEmployeeByEmpNo(long empNo);

	public String getEmployeeByJobDeptno_ARGS = "job, deptno";
	public List getEmployeeByJobDeptno(String job, short deptno);
	
	//HQLを指定して実行する場合
	public String getHQLAllEmployee_HQL = "from Employee emp order by emp.empno";
	public List getHQLAllEmployee();

	//何も指定していない場合
	public List getAllEmployee();

	//firstResult,maxResultsを指定する場合
	public String getEmployeeList_ARGS = "firstResult,maxResults";
	public String getEmployeeList_HQL = "from Employee emp order by emp.empno";
	public List getEmployeeList(int firstResult ,int MaxResults );

	//戻り値がintの場合
	public String getEmployeeCount_HQL = "select count(emp) from Employee emp";
	public int getEmployeeCount();

	//戻り値がStringの場合
	public String getEmployeeNameById_HQL 
				= "select emp.ename from Employee emp where empno = :employeeId ";
	public String getEmployeeNameById_ARGS = "employeeId";
	public String getEmployeeNameById(Long employeeId);

	//NamedQuery呼び出しを使う場合
	//(Employee.hbm.xmlの"examples.hibernate.dao.EmployeeAutoDao_getEmployeeByJob"に対応)
	public String getEmployeeByJob_ARGS = "job";
	public List getEmployeeByJob(String job);

	//NamedQueryで戻り値がStringになるようなSQL文を使う場合
	//(Employee.hbm.xmlの"examples.hibernate.dao.EmployeeAutoDao_getSQLEmployeeNameById"に対応)
	public String getSQLEmployeeNameById_ARGS = "employeeId";
	public String getSQLEmployeeNameById(Long employeeId);	
	
	//NamedQueryで戻り値がLongになるようなSQL文を使う場合
	//(Employee.hbm.xmlの"getSQLEmployeeIdByName"NamedQueryを実行)
	public String getSQLEmployeeIdByName_ARGS = "employeeName";
	public Long getSQLEmployeeIdByName(String employeeName);
}


EmployeeAutoDao.dicon

S2Hibernate.daoを使うのに必要な設定をまとめた"s2hibernate.dicon"をインクルードします。
<components>
    <include path="s2hibernate.dicon"/>
    <component class="examples.hibernate.dao.EmployeeAutoDao">
        <aspect>j2ee.requiredTx</aspect>
        <aspect>s2hibernate.interceptor</aspect>
    </component>
</components>

s2hibernate.dicon

S2Hibernate.daoを使うのに必要な設定をまとめたdiconファイル
<components namespace="s2hibernate">
    <include path="j2ee.dicon"/>
    <component class="org.seasar.hibernate.impl.S2SessionFactoryImpl"/>
    <component name="interceptor" 
		class="org.seasar.hibernate.dao.interceptors.S2HibernateDaoInterceptor"/>
</components>

EmployeeAutoDaoClient.java

diconファイル名以外は、S2Hibernateの基本的な使い方と同じ流れになります。

  1. 作成したdiconファイルのパスを引数にS2Containerを生成
  2. 生成したS2ContainerからgetComponentを呼び出し、登録したDaoを取得する
  3. 取得したDaoのメソッドを実行する
package examples.hibernate.client;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

import examples.hibernate.dao.EmployeeAutoDao;
import examples.hibernate.entity.Employee;

public class EmployeeAutoDaoClient {

	private static final String PATH = 
				"examples/hibernate/client/EmployeeAutoDao.dicon";

	public static void main(String[] args) {
		S2Container container = S2ContainerFactory.create(PATH);/* 手順1 */
		container.init();
		try {
			EmployeeAutoDao dao = (EmployeeAutoDao) container
					.getComponent(EmployeeAutoDao.class);/* 手順2 */
			Employee emp = new Employee();
			emp.setEmpno( 7788);
			emp.setEname("SCOTT");
			emp.setDeptno((short)10);

			dao.save( emp );	/* 手順3 */

		} finally {
			container.destroy();
		}

	}
}

実行結果

DEBUG 2004-11-11 19:01:50,163 [main] トランザクションを開始しました
INFO  2004-11-11 19:01:50,323 [main] Hibernate 2.1.6
省略
DEBUG 2004-11-11 19:01:51,545 [main] 物理的なコネクションを取得しました
DEBUG 2004-11-11 19:01:51,645 [main] 論理的なコネクションを取得しました
省略
Hibernate: insert into EMP (ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, EMPNO)
		values (?, ?, ?, ?, ?, ?, ?, ?)
省略
DEBUG 2004-11-11 19:01:52,025 [main] 論理的なコネクションを閉じました
DEBUG 2004-11-11 19:01:52,025 [main] トランザクションをコミットしました
DEBUG 2004-11-11 19:01:52,045 [main] 物理的なコネクションを閉じました