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

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

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

先打开HibernateDaoSupoprt看看.

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

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

  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()等方法的源码.

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

细心的朋友们可能发现了. 他们无一例外的都调用了一个叫做execute()的方法. 对了. 我们再看看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. FlushMode previousFlushMode = null;
  8. try {
  9. previousFlushMode = applyFlushMode(session, existingTransaction);
  10. enableFilters(session);
  11. Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
  12. Object result = action.doInHibernate(sessionToExpose);
  13. flushIfNecessary(session, existingTransaction);
  14. return result;
  15. }
  16. catch (HibernateException ex) {
  17. throw convertHibernateAccessException(ex);
  18. }
  19. catch (SQLException ex) {
  20. throw convertJdbcAccessException(ex);
  21. }
  22. catch (RuntimeException ex) {
  23. // Callback code threw application exception...
  24. throw ex;
  25. }
  26. finally {
  27. if (existingTransaction) {
  28. logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
  29. disableFilters(session);
  30. if (previousFlushMode != null) {
  31. session.setFlushMode(previousFlushMode);
  32. }
  33. }
  34. else {
  35. SessionFactoryUtils.releaseSession(session, getSessionFactory());
  36. }
  37. }
  38. }

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

  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. static void closeSessionOrRegisterDeferredClose(Session session, SessionFactory sessionFactory) {
  11. Map holderMap = (Map) deferredCloseHolder.get();
  12. if (holderMap != null && sessionFactory != null && holderMap.containsKey(sessionFactory)) {
  13. logger.debug("Registering Hibernate Session for deferred close");
  14. Set sessions = (Set) holderMap.get(sessionFactory);
  15. sessions.add(session);
  16. if (!session.isConnected()) {
  17. // We're running against Hibernate 3.1 RC1, where Hibernate will
  18. // automatically disconnect the Session after a transaction.
  19. // We'll reconnect it here, as the Session is likely gonna be
  20. // used for lazy loading during an "open session in view" pase.
  21. session.reconnect();
  22. }
  23. }
  24. else {
  25. doClose(session);
  26. }
  27. }
  28. private static void doClose(Session session) {
  29. if (session != null) {
  30. logger.debug("Closing Hibernate Session");
  31. try {
  32. session.close();
  33. }
  34. catch (HibernateException ex) {
  35. logger.error("Could not close Hibernate Session", ex);
  36. }
  37. catch (RuntimeException ex) {
  38. logger.error("Unexpected exception on closing Hibernate Session", ex);
  39. }
  40. }
  41. }

spring管理hibernate session的问题探究的更多相关文章

  1. Spring管理Hibernate

    为什么要用Hibernate框架? 既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢? 首先我们来看一下Hibernate进行操作的步骤.比如添 ...

  2. ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存

    ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate  : Hibernate是一个持久层框架,经常访问物理数据库 ...

  3. spring管理hibernate,mybatis,一级缓存失效原因

    mybatis缓存:一级缓存和二级缓存 hibernate缓存:一级缓存和二级缓存 关于缓存: 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器, 其作用是为了减少应 ...

  4. Spring管理Hibernate事务

    在没有加入Spring来管理Hibernate事务之前,Hibernate对事务的管理的顺序是: 开始事务 提交事务 关闭事务 这样做的原因是Hibernate对事务默认是手动提交,如果不想手动提交, ...

  5. Spring管理 hibernate 事务配置的五种方式

    Spring配置文件中关于事务配置总是由三个组成部分,DataSource.TransactionManager和代理机制这三部分,无论是那种配置方法,一般变化的只是代理机制这块! 首先我创建了两个类 ...

  6. [转]利于ThreadLocal管理Hibernate Session

    摘自http://aladdin.iteye.com/blog/40986 在利用Hibernate开发DAO模块时,我们和Session打的交道最多,所以如何合理的管理Session,避免Sessi ...

  7. Spring异常解决 java.lang.NullPointerException,配置spring管理hibernate时出错

    @Repository public class SysUerCDAO { @Autowired private Hibernate_Credit hibernate_credit; /** * 根据 ...

  8. 关于spring管理hibernate事物

    下面这篇文章对我帮助很大.http://blog.csdn.net/jianxin1009/article/details/9202907

  9. Spring对hibernate的事物管理

    把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理.一 ...

随机推荐

  1. node升级更新最近稳定版

    今天,又发现一个超级简单的升级Node.js的方法.一行命令搞定,省去了重新编译安装的过程. node有一个模块叫n(这名字可够短的...),是专门用来管理node.js的版本的. 首先安装n模块: ...

  2. Solr Dismax查询解析器-深入分析

    Solr 支持多种查询解析,给搜索引擎开发人员提供灵活的查询解析.Solr 中主要包含这几个查询解析器:标准查询解析器.DisMax 查询解析器,扩展 DisMax 查询解析器(eDisMax) Di ...

  3. ios7 导航栏适配

    ios ui开发过程中,经常会使用到导航栏,默认的样式比较单一,所以经常需要修改导航栏的样式 ios4: - (void)drawRect:(CGRect)rect { UIImage *image ...

  4. Hadoop2.2.0多节点分布式安装及测试

    众所周知,hadoop在10月底release了最新版2.2.很多国内的技术同仁都马上在网络上推出了自己对新版hadoop的配置心得.这其中主要分为两类: 1.单节点配置 这个太简单了,简单到只要懂点 ...

  5. 31-字符串转为 url 格式的两种不同情况

    将此字符串转为 url 格式的: # 如果是转化对象用:data=urllib.parse.urlencode(values) # 如果是转化字符串:s=urllib.parse.quote(s)

  6. WebBrowser介绍——Javascript与C++互操作

    WebBrowser控件是Microsoft提供的一个用于网页浏览的客户端控件,WebBrowser控件的使用相当广泛,例如很多邮件客户端都是使用可编辑的WebBrowser控件作为写邮件的工具,也有 ...

  7. [分享]PY的Boost自动编译程序 1.1 根据环境自动编译

    Python写的Boost自动编译程序 1.1 改进: 根据自己的环境筛选出已安装环境,并列出 环境提供选择. 支持X64位的自动参数编译. 可以选择编译的参数,其他版本持续改进中 自动编译自动安装到 ...

  8. Java之RandomAccessFile小结

    今天跟大家分享一下javase中的关于I/O的操作: 有时我们需要在文件的末尾追加一些内容,在这时用RandomAccessFile就很好. 这个类有两个构造方法: RandomAccessFile( ...

  9. POJ1269 Intersecting Lines 2017-04-16 19:43 50人阅读 评论(0) 收藏

    Intersecting Lines Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15478   Accepted: 67 ...

  10. Codeforces761A Dasha and Stairs 2017-02-05 23:28 114人阅读 评论(0) 收藏

    A. Dasha and Stairs time limit per test 2 seconds memory limit per test 256 megabytes input standard ...