• spring管理hibernate session的问题探究


    我们再用spring管理hibernate的时候, 我们会继承HibernateDaoSupport 或者HibernateTemplate类.

    我们不知道这两个类之间有什么关系. 也没有去关闭session. 让我很是心不安,他可没有关闭session呀.如果..真的是后果不堪设想.百度了好久, 谷歌了好多. 都没有一个像样的说法. 说spring中HibernateDaoSupport会自己关闭session.

    眼见为实.于是乎决定查看spring源码一探究竟.

    先打开HibernateDaoSupoprt看看.

    Hibernatedaosuport.java代码  收藏代码
    1. public abstract class HibernateDaoSupport extends DaoSupport {  
    2.   
    3.     private HibernateTemplate hibernateTemplate;  
    4.   
    5.  public final void setSessionFactory(SessionFactory sessionFactory) {  
    6.       this.hibernateTemplate = createHibernateTemplate(sessionFactory);  
    7.     }  
    8.   
    9. protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {  
    10.         return new HibernateTemplate(sessionFactory);  
    11.     }  
    12. public final SessionFactory getSessionFactory() {  
    13.         return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);  
    14.     }  
    15. public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) {  
    16.         this.hibernateTemplate = hibernateTemplate;  
    17.     }  
    18. public final HibernateTemplate getHibernateTemplate() {  
    19.       return hibernateTemplate;  
    20.     }  
    21. protected final void checkDaoConfig() {  
    22.         if (this.hibernateTemplate == null) {  
    23.             throw new IllegalArgumentException("sessionFactory or hibernateTemplate is required");  
    24.         }  
    25.     }  
    26. protected final Session getSession()  
    27.         throws DataAccessResourceFailureException, IllegalStateException {  
    28.   
    29.         return getSession(this.hibernateTemplate.isAllowCreate());  
    30.     }  
    31. protected final Session getSession(boolean allowCreate)  
    32.         throws DataAccessResourceFailureException, IllegalStateException {  
    33.   
    34.         return (!allowCreate ?  
    35.             SessionFactoryUtils.getSession(getSessionFactory(), false) :  
    36.                 SessionFactoryUtils.getSession(  
    37.                         getSessionFactory(),  
    38.                         this.hibernateTemplate.getEntityInterceptor(),  
    39.                         this.hibernateTemplate.getJdbcExceptionTranslator()));  
    40.     }  
    41. protected final DataAccessException convertHibernateAccessException(HibernateException ex) {  
    42.         return this.hibernateTemplate.convertHibernateAccessException(ex);  
    43.     }  
    44. protected final void releaseSession(Session session) {  
    45.         SessionFactoryUtils.releaseSession(session, getSessionFactory());  
    46.     }  

    在这里我们会注意到一个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()方法.

    Java代码  收藏代码
    1. public Serializable save(final Object entity) throws DataAccessException {  
    2.         return (Serializable) execute(new HibernateCallback() {  
    3.             public Object doInHibernate(Session session) throws HibernateException {  
    4.                 checkWriteOperationAllowed(session);  
    5.                 return session.save(entity);  
    6.             }  
    7.         }, true);  
    8.     }  

     我们再看看update(), merge(), find()等方法的源码.

    Java代码  收藏代码
    1. //update 方法  
    2.   
    3. public void update(Object entity) throws DataAccessException {  
    4.         update(entity, null);  
    5.     }  
    6.   
    7.     public void update(final Object entity, final LockMode lockMode) throws DataAccessException {  
    8.         execute(new HibernateCallback() {  
    9.             public Object doInHibernate(Session session) throws HibernateException {  
    10.                 checkWriteOperationAllowed(session);  
    11.                 session.update(entity);  
    12.                 if (lockMode != null) {  
    13.                     session.lock(entity, lockMode);  
    14.                 }  
    15.                 return null;  
    16.             }  
    17.         }, true);  
    18.     }  
    19.   
    20.   
    21. //merge()  
    22.   
    23. public Object merge(final Object entity) throws DataAccessException {  
    24.         return execute(new HibernateCallback() {  
    25.             public Object doInHibernate(Session session) throws HibernateException {  
    26.                 checkWriteOperationAllowed(session);  
    27.                 return session.merge(entity);  
    28.             }  
    29.         }, true);  
    30.     }  
    31.   
    32. //find()  
    33. public List find(String queryString) throws DataAccessException {  
    34.         return find(queryString, (Object[]) null);  
    35.     }  
    36.   
    37.     public List find(String queryString, Object value) throws DataAccessException {  
    38.         return find(queryString, new Object[] {value});  
    39.     }  
    40.   
    41.     public List find(final String queryString, final Object[] values) throws DataAccessException {  
    42.         return (List) execute(new HibernateCallback() {  
    43.             public Object doInHibernate(Session session) throws HibernateException {  
    44.                 Query queryObject = session.createQuery(queryString);  
    45.                 prepareQuery(queryObject);  
    46.                 if (values != null) {  
    47.                     for (int i = 0; i < values.length; i++) {  
    48.                         queryObject.setParameter(i, values[i]);  
    49.                     }  
    50.                 }  
    51.                 return queryObject.list();  
    52.             }  
    53.         }, true);  
    54.     }  

     细心的朋友们可能发现了. 他们无一例外的都调用了一个叫做execute()的方法. 对了. 我们再看看execute的面目.到底他干了一件什么样的事情呢?]

    Hibernatetemplate.java execute()方法代码  收藏代码
    1. public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {  
    2.         Session session = getSession();  
    3.         boolean existingTransaction = SessionFactoryUtils.isSessionTransactional(session, getSessionFactory());  
    4.         if (existingTransaction) {  
    5.             logger.debug("Found thread-bound Session for HibernateTemplate");  
    6.         }  
    7.   
    8.         FlushMode previousFlushMode = null;  
    9.         try {  
    10.             previousFlushMode = applyFlushMode(session, existingTransaction);  
    11.             enableFilters(session);  
    12.             Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));  
    13.             Object result = action.doInHibernate(sessionToExpose);  
    14.             flushIfNecessary(session, existingTransaction);  
    15.             return result;  
    16.         }  
    17.         catch (HibernateException ex) {  
    18.             throw convertHibernateAccessException(ex);  
    19.         }  
    20.         catch (SQLException ex) {  
    21.             throw convertJdbcAccessException(ex);  
    22.         }  
    23.         catch (RuntimeException ex) {  
    24.             // Callback code threw application exception...  
    25.             throw ex;  
    26.         }  
    27.         finally {  
    28.             if (existingTransaction) {  
    29.                 logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");  
    30.                 disableFilters(session);  
    31.                 if (previousFlushMode != null) {  
    32.                     session.setFlushMode(previousFlushMode);  
    33.                 }  
    34.             }  
    35.             else {  
    36.                 SessionFactoryUtils.releaseSession(session, getSessionFactory());  
    37.             }  
    38.         }  
    39.     }  

        抛掉其他的不管. 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()

    Java代码  收藏代码
    1. public static void releaseSession(Session session, SessionFactory sessionFactory) {  
    2.         if (session == null) {  
    3.             return;  
    4.         }  
    5.         // Only close non-transactional Sessions.  
    6.         if (!isSessionTransactional(session, sessionFactory)) {  
    7.             closeSessionOrRegisterDeferredClose(session, sessionFactory);  
    8.         }  
    9.     }  
    10.   
    11.  static void closeSessionOrRegisterDeferredClose(Session session, SessionFactory sessionFactory) {  
    12.   Map holderMap = (Map) deferredCloseHolder.get();  
    13.   if (holderMap != null && sessionFactory != null && holderMap.containsKey(sessionFactory)) {  
    14.    logger.debug("Registering Hibernate Session for deferred close");  
    15.    Set sessions = (Set) holderMap.get(sessionFactory);  
    16.    sessions.add(session);  
    17.    if (!session.isConnected()) {  
    18.     // We're running against Hibernate 3.1 RC1, where Hibernate will  
    19.     // automatically disconnect the Session after a transaction.  
    20.     // We'll reconnect it here, as the Session is likely gonna be  
    21.     // used for lazy loading during an "open session in view" pase.  
    22.     session.reconnect();  
    23.    }  
    24.   }  
    25.   else {  
    26.    doClose(session);  
    27.   }  
    28.  }  
    29.     private static void doClose(Session session) {  
    30.         if (session != null) {  
    31.             logger.debug("Closing Hibernate Session");  
    32.             try {  
    33.                 session.close();  
    34.             }  
    35.             catch (HibernateException ex) {  
    36.                 logger.error("Could not close Hibernate Session", ex);  
    37.             }  
    38.             catch (RuntimeException ex) {  
    39.                 logger.error("Unexpected exception on closing Hibernate Session", ex);  
    40.             }  
    41.         }  
    42.     }  
  • 相关阅读:
    获取窗口相对位置小工具
    关于抽奖概率的问题
    乔布斯的成功秘方:坚持思考两个问题
    清理svn生成的相关文件的小工具
    photoshop cs6 简体中文正式版下载
    .NET下office操作利器NPOI
    sql 取各组中的最大值
    c# winform 获取当前程序运行根目录
    C# Winform DataGridView使用总结 转
    c#安装数据库并自动修改Web.config类
  • 原文地址:https://www.cnblogs.com/yangmengdx3/p/4423163.html
Copyright © 2020-2023  润新知