getHibernateTemplate().merge(user);
会先查询,然后执行update语句
getSession().merge(user);
我的userid是存在.而且手动填
能说说什么时候用HibernateTemplate,什么时候用Session吗?
区别在哪里呢..谢谢了..
[quote]加了commit 一样不能更新 [/quote]
上代码看看 8)
"getHibernateTemplate已经封装好了一些基本的方法,可以直接去用,也就是template嘛,
而getSession只是获取一个数据工厂的session,然后大部分方法都需要自己写,加hql语句,然后用query方法执行
谈不上什么优点缺点,类似添加删除更新这样的可以直接用getHibernateTemplate而大部分带条件查询的就需要用getSession自己写了"
搜索到的,如果自己getSession用于更新数据最好要控制下事物和Session的关闭,否则数据可能不能及时更新。
getHibernateTemplate是驱动hibernate里面已经封装好的一个模板,这就不要你手工去实现一些方法了,跟ibatis里面一样。而getSession是获得一个数据工厂,然后去执行sql或者hql语句,这些都是要你自己来写全的。
[quote]getHibernateTemplate是驱动hibernate里面已经封装好的一个模板,这就不要你手工去实现一些方法了,跟ibatis里面一样。而getSession是获得一个数据工厂,然后去执行sql或者hql语句,这些都是要你自己来写全的。[/quote]
还有用session最好都要commit一下,要不然是不会更新的。
getHibernateTemplate是驱动hibernate里面已经封装好的一个模板,这就不要你手工去实现一些方法了,跟ibatis里面一样。而getSession是获得一个数据工厂,然后去执行sql或者hql语句,这些都是要你自己来写全的。
自己看一下getHibernateTemplate里面的实现就一清二楚啦
:wink: :D :D
可以看看源码追踪一下不就OK了
这个问题主要是由于HibernateTemplate由于要做事务处理造成的,getHibernateTemplate是如此调用的:
[code="java"]
return executeWithNativeSession(new HibernateCallback() {
@SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
return (T) session.merge(entityName, entity);
}
});
...
public <T> T executeWithNativeSession(HibernateCallback<T> action) {
return doExecute(action, false, true);
}
....
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Session session = (enforceNewSession ?
SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());
boolean existingTransaction = (!enforceNewSession &&
(!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));
if (existingTransaction) {
logger.debug("Found thread-bound Session for HibernateTemplate");
}
FlushMode previousFlushMode = null;
try {
previousFlushMode = applyFlushMode(session, existingTransaction);
enableFilters(session);
Session sessionToExpose =
(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
T result = action.doInHibernate(sessionToExpose);
flushIfNecessary(session, existingTransaction);//差别就在这里
return result;
}
catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
catch (SQLException ex) {
throw convertJdbcAccessException(ex);
}
catch (RuntimeException ex) {
// Callback code threw application exception...
throw ex;
}
finally {
if (existingTransaction) {
logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
disableFilters(session);
if (previousFlushMode != null) {
session.setFlushMode(previousFlushMode);
}
}
else {
// Never use deferred close for an explicitly new Session.
if (isAlwaysUseNewSession()) {
SessionFactoryUtils.closeSession(session);
}
else {
SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
}
}
}
}
[/code]
executeWithNativeSession里面会首先从当前事务中取session,如果没有事务才调用的getSession()而且调用flushIfNecessary
HibernateTemplate封装了实现的细节,包括try...catch,只能抛出unchecked exception.因此如果你不想自己处理异常细节时就用HibernateTemplate的merge方法,否则就用Session的merge方法。
[quote]我的方法中 值有一句代码
user 是有值得参数
getHibernateTemplate().merge(user); //这样是可以的
getSession().merge(user); //这样不行
//加commit
Transaction t = getSession().beginTransaction();
t.begin();
getSession().merge(user);
t.commit();
这样也是不行的 [/quote]
[code="java"]
Session session = getSession();
Transaction t = getSession().beginTransaction();
t.begin();
session.merge(user);
t.commit();
[/code]
这样不行吗? 8)
getSession()这个方法是怎么做的?应该跟org.springframework.orm.hibernate3.HibernateTemplate.getSession()是不一样的吧。HibernateTemplate.getSession()首先会从当前线程变量成取绑定的会话。
从spring里拿session时,spring会设置一些黑夜参数的,这是我的猜测。如果你有兴趣去验证一下的话,请把你的调用方法声明成可写事务,看看能不能提交上去,如果能话,那你再把事务去掉,再运行一次,然后debug一下session的参数,参数肯定有区别,如果你对session理解深的话,根据两个session的参数不一样你就能分析出回去,否则你就degug进去,看看hibernate根据不同的参数走了什么逻辑。