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管理.一 ...
随机推荐
- Selection II
[Selection II] 1.上.下.左.右键可以移动Selection 1个像素.按住Shift键,可以一次移动10个像素. 2.Add Selection模式的快捷键是Shift,Sub Se ...
- codeforces:MEX Queries分析和实现
首先说明一下MEX,设S是自然数集合N的一个子集,那么S的MEX则为min(N\S),即不包含于S的最小自然数. 题目大意是存在一个空集S,提供n组输入(n<10^5),每组输入对应下面的一个指 ...
- 综合:bool类型 命名空间 输入输出
----------siwuxie095 题目要求: 使用一个函数找出一个整型数组中的最大值或最小值 注意: 1.直接书写 cin cout endl, ...
- 打劫房屋 · House Robber
[抄题]: 假设你是一个专业的窃贼,准备沿着一条街打劫房屋.每个房子都存放着特定金额的钱.你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警 ...
- [DT] 数据结构术语中英文对照
数据结构术语中英文对照 数据 Data 数据元素 Data element 数据项 Data item 数据结构 Data structure 逻辑结构 Logical structure 数据类型 ...
- AES CFB/OFB/ECB/CBC/CTR优缺点
AES CFB/OFB/ECB/CBC/CTR优缺点 摘自:http://www.metsky.com/archives/418.html 发表时间:2010年05月11 分类: 网络日志 作者: 天 ...
- WebApi参数传递总结(转)
出处:http://www.cnblogs.com/Juvy/p/3903974.html 在WebAPI中,请求主体(HttpContent)只能被读取一次,不被缓存,只能向前读取的流. 举例子说明 ...
- msfconsole邮件收集器模块
msfconsole search email collector use auxiliary/gather/search_email_collector show options 下面我们设置域名. ...
- C++中break/Continue,exit/return的理解
刚才遇到了一个问题,大概是这样的. func1执行完成,进入func1Complete,其中switch处理func1返回的数据,如果返回数据是clear则重新执行func1. 测试的时候发现func ...
- 自我介绍及注册github和上传文件
自我介绍: 周侃 年龄20 喜好:玩游戏,赚钱,交际 理想:想要改变中国手游界颓靡的时代,让它进入新次元. 注册github,以及上传文件: 今天给大家来讲解下如何注册githup 当我们打开gith ...