[Seasar-user:682] s2hibernateのロールバックについて
B ntt-syscom.co.jp M.Kondo
match
2004年 4月 19日 (月) 13:53:38 JST
はじめまして。
近藤と申します。
実務でJavaを使用した事のない初心者ですが、よろしくお願いいたします。
s2hibernateのサンプルをちょこちょこ変更してお勉強(お遊び?)中です。
(もちろんhibernateも初めてです・・)
s2hibernateでのロールバックの動作を確認したくて、サンプルを以下のように変更しました。
(WindowsXP、j2sdk1.4.2_03、Eclipse2.1.1です)
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
package examples.hibernate.client;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import examples.hibernate.entity.Employee;
import examples.hibernate.service.EmployeeService;
public class EmployeeClient {
private static final String PATH =
"examples/hibernate/client/Employee-config.xml";
public static void main(String[] args) {
S2Container container = S2ContainerFactory.create(PATH);
container.init();
try {
EmployeeService service =
(EmployeeService) container.getComponent(EmployeeService.class);
printAllEmployees(service);
saveEmployees(service);
printAllEmployees(service);
} catch (Exception ex) {
System.out.println("異常発生");
ex.printStackTrace();
} finally {
container.destroy();
}
}
private static void printAllEmployees(EmployeeService service) {
List allEmployees = service.getAllEmployees();
for (Iterator it = allEmployees.iterator(); it.hasNext();) {
Employee emp = (Employee) it.next();
System.out.println(emp.getEmpno() + " :" + emp.getEname());
}
}
private static void saveEmployees(EmployeeService service) {
Employee emp1 = new Employee(
1111,
"match1",
"AAA",
new Short("111"),
new Date(),
new Float(111),
new Float(111),
(short)1);
Employee emp2 = new Employee(
7369,
"match2",
"BBB",
new Short("222"),
new Date(),
new Float(222),
new Float(222),
(short)2);
List employees = new ArrayList();
employees.add(emp1);
employees.add(emp2);
service.saveEmployees(employees);
}
}
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
(実際にはEmployeeService、EmployeeServiceImpl、EmployeeDao、EmployeeDaoImplも
EmployeeClientに沿って変更しています。その他のソース・設定ファイル・DBの内容はサンプルのままです)
予想していた動作としては
1.emp2のempno(主キー)「7369」がすでにDBに登録されているため、hibernateで例外発生。
2.ログ上には「トランザクションをロールバックしました」と表示される。
3.emp1、emp2は同一トランザクションなので両方ともロールバックされる。
4.EmployeeClient#mainで例外をキャッチし、「異常発生」と出力される。
しかし、実際に実行したところ下記のような結果になってしまいました。
1.emp2のempno(主キー)「7369」がすでにDBに登録されているため、hibernateで例外発生。
2.ログ上には「トランザクションをコミットしました」と表示される。
3.emp1はDBに登録されてしまった。
4.EmployeeClient#mainに例外はスローされてこなかった。
emp2のempno(主キー)を「7369」以外にした場合は、emp1・emp2とも正常に登録されたので
(たぶん)EmployeeService、EmployeeServiceImpl、EmployeeDao、EmployeeDaoImpl等で
変なコーディングはしていないと思うのですが・・・
使用方法とかコーディングに誤りがありましたらご教授ください。
以下は実行時のログです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
DEBUG 2004-04-19 11:28:49,343 [main] トランザクションを開始しました
DEBUG 2004-04-19 11:28:50,359 [main] 物理的なコネクションを取得しました
DEBUG 2004-04-19 11:28:50,375 [main] 論理的なコネクションを取得しました
Hibernate: select employee0_.EMPNO as EMPNO, employee0_.ENAME as ENAME, employee
0_.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 empl
oyee0_
DEBUG 2004-04-19 11:28:50,718 [main] 論理的なコネクションを閉じました
DEBUG 2004-04-19 11:28:50,734 [main] トランザクションをコミットしました
7369 :SMITH
7499 :ALLEN
7521 :WARD
7566 :JONES
7654 :MARTIN
7698 :BLAKE
7782 :CLARK
7788 :SCOTT
7839 :KING
7844 :TURNER
7876 :ADAMS
7900 :JAMES
7902 :FORD
7934 :MILLER
DEBUG 2004-04-19 11:28:50,734 [main] トランザクションを開始しました
DEBUG 2004-04-19 11:28:50,734 [main] 論理的なコネクションを取得しました
Hibernate: insert into EMP (ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, EMPNO)
values (?, ?, ?, ?, ?, ?, ?, ?)
DEBUG 2004-04-19 11:28:50,796 [main] 論理的なコネクションを閉じました
ERROR 2004-04-19 11:28:50,812 [main] [EHBN0001]Hibernateで例外が発生しました。理由はnet.sf.hib
ernate.JDBCException: could not insert: [examples.hibernate.entity.Employee#7369]
org.seasar.hibernate.HibernateRuntimeException: [EHBN0001]Hibernateで例外が発生しました。理由
はnet.sf.hibernate.JDBCException: could not insert: [examples.hibernate.entity.Em
ployee#7369]
at org.seasar.hibernate.impl.S2SessionImpl.flush(S2SessionImpl.java:52)
at org.seasar.hibernate.impl.S2SessionFactoryImpl.closeSession(S2SessionFactory
Impl.java:147)
at org.seasar.hibernate.impl.S2SessionFactoryImpl.beforeCompletion(S2SessionFac
toryImpl.java:129)
at org.seasar.extension.jta.TransactionImpl.beforeCompletion(TransactionImpl.ja
va:170)
at org.seasar.extension.jta.TransactionImpl.commit(TransactionImpl.java:133)
at org.seasar.extension.jta.TransactionManagerImpl.commit(TransactionManagerImp
l.java:47)
at org.seasar.extension.tx.AbstractTxAdvice.commit(AbstractTxAdvice.java:52)
at org.seasar.extension.tx.RequiredAdvice.invoke(RequiredAdvice.java:30)
at org.seasar.framework.aop.impl.JoinpointImpl.proceed(JoinpointImpl.java:96)
at org.seasar.framework.aop.proxy.AopProxy.intercept(AopProxy.java:96)
at examples.hibernate.service.EmployeeServiceImpl$$EnhancerByCGLIB$$76e5a108.sa
veEmployees(<generated>)
at examples.hibernate.client.EmployeeClient.saveEmployees(EmployeeClient.java:6
9)
at examples.hibernate.client.EmployeeClient.main(EmployeeClient.java:27)
Caused by: net.sf.hibernate.JDBCException: could not insert: [examples.hibernate
..entity.Employee#7369]
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:478)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:442)
at net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:29)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2382)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2335)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2204)
at org.seasar.hibernate.impl.S2SessionImpl.flush(S2SessionImpl.java:50)
... 12 more
Caused by: java.sql.SQLException: Violation of unique index: SYS_PK_EMP in state
ment [insert into EMP (ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, EMPNO) valu
es ('match2', 'BBB', 222, '2004-04-19 11:28:50.734', 222.0E0, 222.0E0, 2, 7369)]
at org.hsqldb.Trace.getError(Unknown Source)
at org.hsqldb.Result.<init>(Unknown Source)
at org.hsqldb.jdbcConnection.executeHSQL(Unknown Source)
at org.hsqldb.jdbcConnection.execute(Unknown Source)
at org.hsqldb.jdbcStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbcStatement.executeUpdate(Unknown Source)
at org.hsqldb.jdbcPreparedStatement.executeUpdate(Unknown Source)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:
22)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:468)
... 18 more
DEBUG 2004-04-19 11:28:50,812 [main] トランザクションをコミットしました
DEBUG 2004-04-19 11:28:50,812 [main] トランザクションを開始しました
DEBUG 2004-04-19 11:28:50,812 [main] 論理的なコネクションを取得しました
Hibernate: select employee0_.EMPNO as EMPNO, employee0_.ENAME as ENAME, employee
0_.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 empl
oyee0_
DEBUG 2004-04-19 11:28:50,828 [main] 論理的なコネクションを閉じました
DEBUG 2004-04-19 11:28:50,828 [main] トランザクションをコミットしました
1111 :match1
7369 :SMITH
7499 :ALLEN
7521 :WARD
7566 :JONES
7654 :MARTIN
7698 :BLAKE
7782 :CLARK
7788 :SCOTT
7839 :KING
7844 :TURNER
7876 :ADAMS
7900 :JAMES
7902 :FORD
7934 :MILLER
DEBUG 2004-04-19 11:28:50,828 [main] 物理的なコネクションを閉じました
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
----
M.Kondo [E-MAIL ADDRESS DELETED]
Seasar-user メーリングリストの案内