HibernateTemplate 類使用 – JAVA編程語言程序開發技術文章

目的:使用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();
        begun = true;
        committed = false;
        rolledBack = false;


        if (timeout > 0) {
            jdbcContext.getConnectionManager().getBatcher().setTransactionTimeout(timeout);
        }


        jdbcContext.afterTransactionBegin(this);
    }



    在直接使用Hibernate時,要在事務結束的時候,寫上一句:tx.commit(),這個commit()的源碼為:


public void commit() throws HibernateException {
        if (!begun) {
            throw new TransactionException(“Transaction not successfully started”);
        }


        log.debug(“commit”); </P

發佈留言