`

hibernate使用sql query时单元测试跑了一部分后就不动了。

阅读更多

我写了很多使用sql query的hibernate的单元测试,但是总是跑了一部分后就停止不前了。

由于特殊原因,我没能对session关闭,因为前人对它进行了封装,session.close()没有暴露,很恶心。

 

后来在数据库中mysql中,mysqladmin -uroot -pbb status,用这条命令查询连接,发现总是停在22个连接,我的测试用了20个连接,这些连接没有关闭。

 

暂时解决办法在hibernate配置文件中修改配置

<property name="minPoolSize" value="2"/>
<property name="maxPoolSize" value="100"/>

<!--把maxPoolSize由原来的20改成100-->

 

这样连接池的最大连接数增加了,测试是能通过了。

 

在我们的应用中,使用Spring的TransactionManager来管理事务,所以就可以放心在HibernateDaoSupport 中使用getSession (),释放的工作会有Spring帮你完成。

 

以下部分转载自:http://javachikuang.iteye.com/blog/261233

 

 

 

getSession()这个方法本身其实返回的是与当前事务绑定的Session对象,在HibernateDaoSupport中使 用,HibernateDaoSupport本身是不负责对这个Session对象进行关闭的,所以在其中有一个对应的releaseSession() 方法,用于关闭Session。

但是一般使用Spring时,我们会采用HibernateTransactionManager进行事务管理,把事务配置在Service层。 此时,它会帮助我们关闭与当前事务绑定的Session对象,这个可以参照HibernateTransactionManager类中的 doCleanupAfterCompletion方法,它是一个抽象方法的实现。再追溯上去,会发现,在事务commit或者rollback的时候, 会有一段finally代码,专门调用执行该方法的代码:

Java代码
  1. finally  {     
  2.             cleanupAfterCompletion(status);     
  3.         }     
  4.     
  5.     private   void  cleanupAfterCompletion(DefaultTransactionStatus status) {     
  6.         status.setCompleted();     
  7.         if  (status.isNewSynchronization()) {     
  8.             TransactionSynchronizationManager.clearSynchronization();     
  9.             TransactionSynchronizationManager.setCurrentTransactionName(null );     
  10.             TransactionSynchronizationManager.setCurrentTransactionReadOnly(false );     
  11.             if  (status.isNewTransaction()) {     
  12.                 TransactionSynchronizationManager.setActualTransactionActive(false );     
  13.             }     
  14.         }     
  15.         if  (status.isNewTransaction()) {     
  16.             doCleanupAfterCompletion(status.getTransaction());     
  17.         }     
  18.         if  (status.getSuspendedResources() !=  null ) {     
  19.             if  (status.isDebug()) {     
  20.                 logger.debug("Resuming suspended transaction" );     
  21.             }     
  22.             resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());     
  23.         }     
  24.     }    
finally {   
            cleanupAfterCompletion(status);   
        }   
  
    private void cleanupAfterCompletion(DefaultTransactionStatus status) {   
        status.setCompleted();   
        if (status.isNewSynchronization()) {   
            TransactionSynchronizationManager.clearSynchronization();   
            TransactionSynchronizationManager.setCurrentTransactionName(null);   
            TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);   
            if (status.isNewTransaction()) {   
                TransactionSynchronizationManager.setActualTransactionActive(false);   
            }   
        }   
        if (status.isNewTransaction()) {   
            doCleanupAfterCompletion(status.getTransaction());   
        }   
        if (status.getSuspendedResources() != null) {   
            if (status.isDebug()) {   
                logger.debug("Resuming suspended transaction");   
            }   
            resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());   
        }   
    }  


故而,只要参与了事务,HibernateTransactionManager会帮你正确关闭Session。

不过很多的web应用都会采用OpenSessionInView模式,也就是Session会被保持到View层。同样经过 HibernateTransactionManager,为什么使用了OpenSessionInView模式以后,Session就不会被关闭呢?这 是由于在获取当前线程绑定事务的时候,有一个判断,如果存在当前线程绑定的Session,会把当前事务对象的newSessionHolder值设置成 false,从而跳过上面的代码中doCleanupAfterCompletion(status.getTransaction());的调用:

Java代码
  1. protected  Object doGetTransaction() {     
  2.         HibernateTransactionObject txObject = new  HibernateTransactionObject();     
  3.         txObject.setSavepointAllowed(isNestedTransactionAllowed());     
  4.     
  5.         if  (TransactionSynchronizationManager.hasResource(getSessionFactory())) {     
  6.             SessionHolder sessionHolder =     
  7.                     (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());     
  8.             if  (logger.isDebugEnabled()) {     
  9.                 logger.debug("Found thread-bound Session ["  +     
  10.                         SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction" );     
  11.             }     
  12.             txObject.setSessionHolder(sessionHolder, false );     
  13.             if  (getDataSource() !=  null ) {     
  14.                 ConnectionHolder conHolder = (ConnectionHolder)     
  15.                         TransactionSynchronizationManager.getResource(getDataSource());     
  16.                 txObject.setConnectionHolder(conHolder);     
  17.             }     
  18.         }     
  19.     
  20.         return  txObject;     
  21.     }    
protected Object doGetTransaction() {   
        HibernateTransactionObject txObject = new HibernateTransactionObject();   
        txObject.setSavepointAllowed(isNestedTransactionAllowed());   
  
        if (TransactionSynchronizationManager.hasResource(getSessionFactory())) {   
            SessionHolder sessionHolder =   
                    (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());   
            if (logger.isDebugEnabled()) {   
                logger.debug("Found thread-bound Session [" +   
                        SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");   
            }   
            txObject.setSessionHolder(sessionHolder, false);   
            if (getDataSource() != null) {   
                ConnectionHolder conHolder = (ConnectionHolder)   
                        TransactionSynchronizationManager.getResource(getDataSource());   
                txObject.setConnectionHolder(conHolder);   
            }   
        }   
  
        return txObject;   
    }  


综合一下,只要使用Spring的TransactionManager来管理事务,就可以放心在HibernateDaoSupport中使用getSession(),释放的工作会有Spring帮你完成。

 

分享到:
评论

相关推荐

    hibernate增删改查和动态sql

    6. **Maven Webapp:** 提到的"curd2 Maven Webapp"可能是指一个使用Maven构建的Web应用程序,其中包含了一个名为"curd2"的模块,这个模块可能包含了上述关于Hibernate CRUD操作和动态SQL的实现。 综上所述,这个...

    Hibernate生产SQL语句

    HQL用于Hibernate,JPQL是JPA规范的一部分。它们可以方便地处理复杂的关联查询和聚合函数。 6. **Java反射**:在模仿Hibernate生成SQL时,Java反射扮演着关键角色。反射允许我们在运行时动态访问类的信息,包括类的...

    MockDatabase:一个模拟数据库,用于对Hibernate Criteria,Query和SQLQuery进行单元测试

    总之,MockDatabase是Java开发者在使用Hibernate进行单元测试时的一个强大工具,它可以帮助确保Criteria、Query和SQLQuery的正确性,同时减少了测试的复杂性和潜在风险。通过使用MockDatabase,开发者可以更加专注于...

    hibernate动态数据库改进版

    Hibernate是一个开源的ORM框架,它允许开发者使用面向对象的方式来操作数据库,通过映射机制将Java对象与数据库表进行对应,从而避免了繁琐的SQL语句编写。 1.2 动态数据库需求 在实际开发中,我们可能需要根据用户...

    hibernate执行外部sql

    3. **创建SQLQuery对象**:在Hibernate中,使用`Session`对象的`createSQLQuery()`方法创建`SQLQuery`对象,这个对象可以执行SQL语句。你可以传递读取到的SQL语句到这个方法。 4. **设置参数和类型**:如果SQL语句...

    Hibernate Query Language

    标题:Hibernate Query Language 描述:Hibernate Query Language培训教材 知识点详解: ### 1. Hibernate Query Language(HQL)概述 Hibernate Query Language,简称HQL,是Hibernate框架中用于执行数据库查询...

    hibernate3中通过nativesql或取部分字段并映射为具体对象的实现

    在Java的持久化框架Hibernate中,除了使用HQL(Hibernate Query Language)进行数据查询外,还可以使用Native SQL来访问数据库。本篇文章将深入探讨在Hibernate3中如何通过Native SQL查询部分字段,并将其映射到具体...

    HQL(Hibernate Query Language):

    综上所述,HQL作为Hibernate的一部分,极大地简化了Java开发者处理数据库查询的复杂性,提高了开发效率,并促进了代码的可维护性和可扩展性。通过深入学习HQL,开发者可以更好地掌握Hibernate框架,提高在企业级项目...

    使用Hibernate开发租房系统910

    我们可以使用JUnit和Hibernate Test工具来编写单元测试,确保数据库操作的正确性。 综上所述,"使用Hibernate开发租房系统910"涵盖了对象关系映射、配置、CRUD操作、事务管理、查询、缓存和测试等多个核心主题。...

    Hibernate_query查询数据表中部分字段.

    本文将深入探讨如何使用Hibernate进行数据表中的部分字段查询,这在实际开发中是非常常见的需求。 首先,理解Hibernate的核心概念:实体(Entity)、持久化类(Persistent Class)和映射文件(Mapping File)。实体...

    maven+hibernate

    4. **Spring MVC**: Spring MVC是Spring框架的一部分,用于构建Web应用程序。它提供了模型、视图和控制器的分离,使开发者能够更专注于业务逻辑。在Spring MVC中,可以使用DispatcherServlet来处理HTTP请求,...

    自己动手模仿Hibernate写数据库框架

    10. **测试与文档**:创建单元测试以验证框架的功能,同时编写清晰的文档,帮助其他开发者理解和使用我们的框架。 在"DButils"这个压缩包子文件的文件名称列表中,我们可以推测作者可能使用了Apache的DBUtils工具库...

    SQL语句拼接

    尽管使用`StringBuffer`拼接SQL语句是一种简单有效的方法,但它也存在一些潜在的安全隐患,尤其是在处理用户输入时。例如,如果用户提交恶意输入,可能会导致SQL注入攻击。为了避免这种情况的发生,建议采用以下措施...

    Hibernate在Myeclipse下SQL语句演示

    在Myeclipse这样的集成开发环境中,使用Hibernate可以方便地进行SQL语句的编写和调试。本演示将重点讲解如何在Myeclipse下利用Hibernate执行HQL(Hibernate Query Language)和Criteria查询。 ### Hibernate核心...

    hibernate sql案例

    在使用Hibernate执行SQL查询时,我们通常有以下几种方式: 1. HQL(Hibernate Query Language):这是Hibernate专有的查询语言,语法类似于SQL,但面向对象。例如,我们可以用`from Customer`来获取所有Customer...

    Hibernate的Template方法以及SQL简介

    与`get`方法类似,但`load`方法会在找不到对应实体时抛出异常。 3. **全表查询** ```java Query query = session.createQuery("from Order"); List&lt;Order&gt; list = query.list(); ``` 此方法用于查询表中的...

    hibernate使用的jar包

    9. **jta-1.1.jar**:Java Transaction API(JTA)是Java平台的一部分,用于处理分布式事务。Hibernate支持JTA,因此需要引入这个jar包来处理跨多个资源的事务。 10. **jboss-transaction-api_1.1_spec-1.0.0.Beta1...

    Java 使用注解拼接SQL语句

    例如,我们可以创建一个切面,该切面会在方法调用前/后检查是否有`@Query`注解,并根据注解中的SQL模板执行数据库操作。 3. **动态SQL**: 使用注解拼接SQL的一个关键优点是动态性。例如,我们可以根据方法参数...

    spring_Framework+经典SQL语句大全+Hibernate中文API

    它支持CRUD(Create, Read, Update, Delete)操作,关联映射,缓存机制,以及HQL(Hibernate Query Language),使得SQL与Java对象之间的交互更加简单直观。 在"spring_Framework+经典SQL语句大全+Hibernate中文API...

Global site tag (gtag.js) - Google Analytics