spring管理hibernate session的问题探究
我们再用spring管理hibernate的时候, 我们会继承HibernateDaoSupport 或者HibernateTemplate类.
我们不知道这两个类之间有什么关系. 也没有去关闭session. 让我很是心不安,他可没有关闭session呀.如果..真的是后果不堪设想.百度了好久, 谷歌了好多. 都没有一个像样的说法. 说spring中HibernateDaoSupport会自己关闭session.
眼见为实.于是乎决定查看spring源码一探究竟.
先打开HibernateDaoSupoprt看看.
- public abstract class HibernateDaoSupport extends DaoSupport {
 - private HibernateTemplate hibernateTemplate;
 - public final void setSessionFactory(SessionFactory sessionFactory) {
 - this.hibernateTemplate = createHibernateTemplate(sessionFactory);
 - }
 - protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
 - return new HibernateTemplate(sessionFactory);
 - }
 - public final SessionFactory getSessionFactory() {
 - return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);
 - }
 - public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
 - this.hibernateTemplate = hibernateTemplate;
 - }
 - public final HibernateTemplate getHibernateTemplate() {
 - return hibernateTemplate;
 - }
 - protected final void checkDaoConfig() {
 - if (this.hibernateTemplate == null) {
 - throw new IllegalArgumentException("sessionFactory or hibernateTemplate is required");
 - }
 - }
 - protected final Session getSession()
 - throws DataAccessResourceFailureException, IllegalStateException {
 - return getSession(this.hibernateTemplate.isAllowCreate());
 - }
 - protected final Session getSession(boolean allowCreate)
 - throws DataAccessResourceFailureException, IllegalStateException {
 - return (!allowCreate ?
 - SessionFactoryUtils.getSession(getSessionFactory(), false) :
 - SessionFactoryUtils.getSession(
 - getSessionFactory(),
 - this.hibernateTemplate.getEntityInterceptor(),
 - this.hibernateTemplate.getJdbcExceptionTranslator()));
 - }
 - protected final DataAccessException convertHibernateAccessException(HibernateException ex) {
 - return this.hibernateTemplate.convertHibernateAccessException(ex);
 - }
 - protected final void releaseSession(Session session) {
 - SessionFactoryUtils.releaseSession(session, getSessionFactory());
 - }
 
在这里我们会注意到一个private 对象. 那就是HibernateTemplate. 这里面也有一个HibernateTemplate的set. get.
哦: 原来如此.呵呵,很白痴的事.
比如说. BaseDao extends HibernateDaoSupport 我们会super.getHibernateTemplate.find(hql);
super.getHibernateTemplate.save(obj);
和BaseDao extends HibernateTemplate 中super.find(hql)和super.save(obj);是等效的. 
 原来没有思考害的我改了一个多小时. 汗..
下面我们来看看HibernateTemplate是怎么样来操作session的呢.
照样我们贴出源代码. 由于这个类代码较多. 我只贴出来几个代表性的属性和方法, 供大家参考.
public class HibernateTemplate extends HibernateAccessor implements HibernateOperations {
private boolean allowCreate = true;
private boolean alwaysUseNewSession = false;
private boolean exposeNativeSession = false;
private boolean checkWriteOperations = true;
private boolean cacheQueries = false;
private String queryCacheRegion;
private int fetchSize = 0;
private int maxResults = 0;
public void ......();
} 一系列的方法.
下面我们看看save()方法.
- public Serializable save(final Object entity) throws DataAccessException {
 - return (Serializable) execute(new HibernateCallback() {
 - public Object doInHibernate(Session session) throws HibernateException {
 - checkWriteOperationAllowed(session);
 - return session.save(entity);
 - }
 - }, true);
 - }
 
我们再看看update(), merge(), find()等方法的源码.
- //update 方法
 - public void update(Object entity) throws DataAccessException {
 - update(entity, null);
 - }
 - public void update(final Object entity, final LockMode lockMode) throws DataAccessException {
 - execute(new HibernateCallback() {
 - public Object doInHibernate(Session session) throws HibernateException {
 - checkWriteOperationAllowed(session);
 - session.update(entity);
 - if (lockMode != null) {
 - session.lock(entity, lockMode);
 - }
 - return null;
 - }
 - }, true);
 - }
 - //merge()
 - public Object merge(final Object entity) throws DataAccessException {
 - return execute(new HibernateCallback() {
 - public Object doInHibernate(Session session) throws HibernateException {
 - checkWriteOperationAllowed(session);
 - return session.merge(entity);
 - }
 - }, true);
 - }
 - //find()
 - public List find(String queryString) throws DataAccessException {
 - return find(queryString, (Object[]) null);
 - }
 - public List find(String queryString, Object value) throws DataAccessException {
 - return find(queryString, new Object[] {value});
 - }
 - public List find(final String queryString, final Object[] values) throws DataAccessException {
 - return (List) execute(new HibernateCallback() {
 - public Object doInHibernate(Session session) throws HibernateException {
 - Query queryObject = session.createQuery(queryString);
 - prepareQuery(queryObject);
 - if (values != null) {
 - for (int i = 0; i < values.length; i++) {
 - queryObject.setParameter(i, values[i]);
 - }
 - }
 - return queryObject.list();
 - }
 - }, true);
 - }
 
细心的朋友们可能发现了. 他们无一例外的都调用了一个叫做execute()的方法. 对了. 我们再看看execute的面目.到底他干了一件什么样的事情呢?]
- public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
 - Session session = getSession();
 - boolean existingTransaction = 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 = (exposeNativeSession ? session : createSessionProxy(session));
 - Object 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 {
 - SessionFactoryUtils.releaseSession(session, getSessionFactory());
 - }
 - }
 - }
 
抛掉其他的不管. finally中我们可以看到. 如果existingTransaction 他会
logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
disableFilters(session);
if (previousFlushMode != null) {
session.setFlushMode(previousFlushMode);
}
他并没有立即关闭session.
否则
SessionFactoryUtils.releaseSession(session, getSessionFactory());
他释放掉了session . 真的close()了吗?
我们在看看sessionFactoryUtil.的releaseSession()
- public static void releaseSession(Session session, SessionFactory sessionFactory) {
 - if (session == null) {
 - return;
 - }
 - // Only close non-transactional Sessions.
 - if (!isSessionTransactional(session, sessionFactory)) {
 - closeSessionOrRegisterDeferredClose(session, sessionFactory);
 - }
 - }
 - static void closeSessionOrRegisterDeferredClose(Session session, SessionFactory sessionFactory) {
 - Map holderMap = (Map) deferredCloseHolder.get();
 - if (holderMap != null && sessionFactory != null && holderMap.containsKey(sessionFactory)) {
 - logger.debug("Registering Hibernate Session for deferred close");
 - Set sessions = (Set) holderMap.get(sessionFactory);
 - sessions.add(session);
 - if (!session.isConnected()) {
 - // We're running against Hibernate 3.1 RC1, where Hibernate will
 - // automatically disconnect the Session after a transaction.
 - // We'll reconnect it here, as the Session is likely gonna be
 - // used for lazy loading during an "open session in view" pase.
 - session.reconnect();
 - }
 - }
 - else {
 - doClose(session);
 - }
 - }
 - private static void doClose(Session session) {
 - if (session != null) {
 - logger.debug("Closing Hibernate Session");
 - try {
 - session.close();
 - }
 - catch (HibernateException ex) {
 - logger.error("Could not close Hibernate Session", ex);
 - }
 - catch (RuntimeException ex) {
 - logger.error("Unexpected exception on closing Hibernate Session", ex);
 - }
 - }
 - }
 
spring管理hibernate session的问题探究的更多相关文章
- Spring管理Hibernate
		
为什么要用Hibernate框架? 既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢? 首先我们来看一下Hibernate进行操作的步骤.比如添 ...
 - ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
		
ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate : Hibernate是一个持久层框架,经常访问物理数据库 ...
 - spring管理hibernate,mybatis,一级缓存失效原因
		
mybatis缓存:一级缓存和二级缓存 hibernate缓存:一级缓存和二级缓存 关于缓存: 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器, 其作用是为了减少应 ...
 - Spring管理Hibernate事务
		
在没有加入Spring来管理Hibernate事务之前,Hibernate对事务的管理的顺序是: 开始事务 提交事务 关闭事务 这样做的原因是Hibernate对事务默认是手动提交,如果不想手动提交, ...
 - Spring管理 hibernate 事务配置的五种方式
		
Spring配置文件中关于事务配置总是由三个组成部分,DataSource.TransactionManager和代理机制这三部分,无论是那种配置方法,一般变化的只是代理机制这块! 首先我创建了两个类 ...
 - [转]利于ThreadLocal管理Hibernate Session
		
摘自http://aladdin.iteye.com/blog/40986 在利用Hibernate开发DAO模块时,我们和Session打的交道最多,所以如何合理的管理Session,避免Sessi ...
 - Spring异常解决 java.lang.NullPointerException,配置spring管理hibernate时出错
		
@Repository public class SysUerCDAO { @Autowired private Hibernate_Credit hibernate_credit; /** * 根据 ...
 - 关于spring管理hibernate事物
		
下面这篇文章对我帮助很大.http://blog.csdn.net/jianxin1009/article/details/9202907
 - Spring对hibernate的事物管理
		
把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理.一 ...
 
随机推荐
- tomcat安装出现问题及解决方法
			
1. tomcat安装: 安装目录-->D:\Program Files\apache-tomcat-7.0.59 2. tomcat环境变量配置: 3. D:\Program Files\ap ...
 - Hadoop Pipes
			
[Hadoop Pipes] 1.MapContext的getInputSplit()可以用于获取当前mapper所对象的文件路经,也就是Pipes中,没有InputSplit接口/对象. 2.在Pi ...
 - shell如何传递变量到另一个脚本文件中
			
http://www.jbxue.com/article/shell/20707.html本文介绍了shell脚本传递变量到另一个脚本文件中的方法,在脚本中调用另一脚本,即创建了一个子进程,感兴趣的朋 ...
 - JavaScript 对象属性作实参以及实参对象的callee属性
			
参考自<<JavaScript权威指南 第6版>> /* * 将对象属性用作实参, 从而不必记住参数的顺序. */ function arraycopy(from,from_s ...
 - IE(IE6/IE7/IE8)支持HTML5标签
			
让IE(ie6/ie7/ie8)支持HTML5元素,我们需要在HTML头部添加以下JavaScript,这是一个简单的document.createElement声明,利用条件注释针对IE来调用这个j ...
 - awk基础02-变量-分隔符-数组
			
对任意一门语言都会有变量,在awk中变量分为内置变量和自定义变量. 内置变量:就是预先在awk中定义好的,用户可以直接使用 自定义变量:这种变量为用户自己定义的变量,需要先定义后再使用. 内置 ...
 - Python WebDriver + Firefox 文件下载
			
firefox可以通过 在地址栏输入:about:config 或about:aupport 来查看或修改配置信息. 这里有两种解决方式, 1.设置自动保存下载 如下图勾选:以后自动采用相同的动作处理 ...
 - oracle树形语句
			
oracle树查询的最重要的就是select…start with…connect by…prior语法了.依托于该语法,我们可以将一个表形结构的以树的顺序列出来.在下面列述了oracle中树型查询的 ...
 - 企业搜索引擎开发之连接器connector(十七)
			
本文描述连接器的提供与外界交互的servlet接口,连接器与外部是通过xml格式数据交互的 1) 获取所有连接类型 提交地址:http://localhost:8080/connector-mana ...
 - Git Note - git tag
			
git tag is used to create labels, usually for version numbers. Format: git tag <TagName> <r ...