getHibernateTemplate().getSessionFactory().getCurrentSession()的意思是得到當前線程
綁定的session,而當前線程綁定的session是通過當前的事務產生的,如果你沒有配置事務的話,當前線程threadlocal中就不存在
session,這樣就出現no session錯誤。
而execute的回調方法,看源碼HibernateTemplate中寫道
public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Session session = getSession();
boolean existingTransaction = (!isAlwaysUseNewSession() &&
(!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));
其中getSession,代碼如下
protected Session getSession() {
if (isAlwaysUseNewSession()) {
return SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor());
}
else if (isAllowCreate()) {
return SessionFactoryUtils.getSession(
getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator());
}
else {
try {
return getSessionFactory().getCurrentSession();
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException("Could not obtain current Hibernate Session", ex);
}
}
}
其中默認private boolean alwaysUseNewSession = false,所以代碼會走到else if (isAllowCreate())
注意這里:else if (isAllowCreate()),其中在HibernateTemplate類中默認private boolean allowCreate = true;
意思說如果當前線程中的session不存在的話,是否允許創建,而默認是允許的,通過函數名字就很清楚,接下來是創建當前線程中的session的代碼,所以在沒有事務的狀態下,用execute回調方法,就不會出現上述問題。