HibernateTemplate 类使用(一)

2014-11-24 00:14:20 · 作者: · 浏览: 0

目的:使用HibernateTemplate执行execute(new HibernateCallback())方法,从HibernateCallback中得到session,在此session中做多个操作,并希望这些操作位于同一个事务中。

如果你这样写(1):

public static void main(String ss[]) {
CtxUtil.getBaseManager().getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
// 保存stu1
Student stu1 = new Student();
stu1.setName("aaaa");// 在数据库中,name字段不允许为null
session.save(stu1);
session.flush();//实际上,如果不是程序员"手痒"来调用这个flush(),HibernateTemplate中session的事务处理还是很方便的

Student stu2 = new Student();
session.save(stu2);// 没有设置name字段,预期会报出例外
session.flush();
return null;
}
});

}


你期望spring在执行完execute回调后,在关闭session的时候提交事务,想法是很好的,但spring并不会这么做。让我们来看看在Hibernate的源代码中,session.beginTransation()做了什么事。看如下代码(2):

public Transaction beginTransaction() throws HibernateException {
errorIfClosed();
if ( rootSession != null ) {
// todo : should seriously consider not allowing a txn to begin from a child session
// can always route the request to the root session
log.warn( "Transaction started on non-root session" );
}
Transaction result = getTransaction();
result.begin();
return result;
}


这个方法中的result是一个org.hibernate.transaction.JDBCTransaction实例,而方法中的getTransaction()方法源代码为(3):

public Transaction getTransaction() throws HibernateException {
if (hibernateTransaction==null) {
log.error(owner.getFactory().getSettings()
.getTransactionFactory().getClass());
hibernateTransaction = owner.getFactory().getSettings()
.getTransactionFactory()
.createTransaction( this, owner );
}
return hibernateTransaction;
}


再次追踪,owner.getFactory()。getSettings() .getTransactionFactory()的createTransaction()方法源代码如下(4):

public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
throws HibernateException {
return new JDBCTransaction( jdbcContext, transactionContext );
}


它返回了一个JDBCTransaction,没什么特别的。

在代码2中,执行了result.begin(),其实也就是JDBCTransaction实例的begin()方法,来看看(5):

public void begin() throws HibernateException {
if (begun) {
return;
}
if (commitFailed) {
throw new TransactionException("cannot re-start transaction after failed commit");
}
log.debug("begin");
try {
toggleAutoCommit = jdbcContext.connection().getAutoCommit();
if (log.isDebugEnabled()) {
log.debug("current autocommit status: " + toggleAutoCommit);
}
if (toggleAutoCommit) {
log.debug("disabling autocommit");
jdbcContext.connection().setAutoCommit(false);//把自动提交设为了false
}
} catch (SQLException e) {
log.error("JDBC begin failed", e);
throw new TransactionException("JDBC begin failed: ", e);
}
callback = jdbcContext.registerCallbackIfNecessary();
b