我写了很多使用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代码,专门调用执行该方法的代码:
-
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());
-
}
-
}
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());的调用:
-
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;
-
}
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帮你完成。
分享到:
相关推荐
6. **Maven Webapp:** 提到的"curd2 Maven Webapp"可能是指一个使用Maven构建的Web应用程序,其中包含了一个名为"curd2"的模块,这个模块可能包含了上述关于Hibernate CRUD操作和动态SQL的实现。 综上所述,这个...
HQL用于Hibernate,JPQL是JPA规范的一部分。它们可以方便地处理复杂的关联查询和聚合函数。 6. **Java反射**:在模仿Hibernate生成SQL时,Java反射扮演着关键角色。反射允许我们在运行时动态访问类的信息,包括类的...
总之,MockDatabase是Java开发者在使用Hibernate进行单元测试时的一个强大工具,它可以帮助确保Criteria、Query和SQLQuery的正确性,同时减少了测试的复杂性和潜在风险。通过使用MockDatabase,开发者可以更加专注于...
Hibernate是一个开源的ORM框架,它允许开发者使用面向对象的方式来操作数据库,通过映射机制将Java对象与数据库表进行对应,从而避免了繁琐的SQL语句编写。 1.2 动态数据库需求 在实际开发中,我们可能需要根据用户...
3. **创建SQLQuery对象**:在Hibernate中,使用`Session`对象的`createSQLQuery()`方法创建`SQLQuery`对象,这个对象可以执行SQL语句。你可以传递读取到的SQL语句到这个方法。 4. **设置参数和类型**:如果SQL语句...
标题:Hibernate Query Language 描述:Hibernate Query Language培训教材 知识点详解: ### 1. Hibernate Query Language(HQL)概述 Hibernate Query Language,简称HQL,是Hibernate框架中用于执行数据库查询...
在Java的持久化框架Hibernate中,除了使用HQL(Hibernate Query Language)进行数据查询外,还可以使用Native SQL来访问数据库。本篇文章将深入探讨在Hibernate3中如何通过Native SQL查询部分字段,并将其映射到具体...
综上所述,HQL作为Hibernate的一部分,极大地简化了Java开发者处理数据库查询的复杂性,提高了开发效率,并促进了代码的可维护性和可扩展性。通过深入学习HQL,开发者可以更好地掌握Hibernate框架,提高在企业级项目...
我们可以使用JUnit和Hibernate Test工具来编写单元测试,确保数据库操作的正确性。 综上所述,"使用Hibernate开发租房系统910"涵盖了对象关系映射、配置、CRUD操作、事务管理、查询、缓存和测试等多个核心主题。...
本文将深入探讨如何使用Hibernate进行数据表中的部分字段查询,这在实际开发中是非常常见的需求。 首先,理解Hibernate的核心概念:实体(Entity)、持久化类(Persistent Class)和映射文件(Mapping File)。实体...
4. **Spring MVC**: Spring MVC是Spring框架的一部分,用于构建Web应用程序。它提供了模型、视图和控制器的分离,使开发者能够更专注于业务逻辑。在Spring MVC中,可以使用DispatcherServlet来处理HTTP请求,...
10. **测试与文档**:创建单元测试以验证框架的功能,同时编写清晰的文档,帮助其他开发者理解和使用我们的框架。 在"DButils"这个压缩包子文件的文件名称列表中,我们可以推测作者可能使用了Apache的DBUtils工具库...
尽管使用`StringBuffer`拼接SQL语句是一种简单有效的方法,但它也存在一些潜在的安全隐患,尤其是在处理用户输入时。例如,如果用户提交恶意输入,可能会导致SQL注入攻击。为了避免这种情况的发生,建议采用以下措施...
在Myeclipse这样的集成开发环境中,使用Hibernate可以方便地进行SQL语句的编写和调试。本演示将重点讲解如何在Myeclipse下利用Hibernate执行HQL(Hibernate Query Language)和Criteria查询。 ### Hibernate核心...
在使用Hibernate执行SQL查询时,我们通常有以下几种方式: 1. HQL(Hibernate Query Language):这是Hibernate专有的查询语言,语法类似于SQL,但面向对象。例如,我们可以用`from Customer`来获取所有Customer...
与`get`方法类似,但`load`方法会在找不到对应实体时抛出异常。 3. **全表查询** ```java Query query = session.createQuery("from Order"); List<Order> list = query.list(); ``` 此方法用于查询表中的...
9. **jta-1.1.jar**:Java Transaction API(JTA)是Java平台的一部分,用于处理分布式事务。Hibernate支持JTA,因此需要引入这个jar包来处理跨多个资源的事务。 10. **jboss-transaction-api_1.1_spec-1.0.0.Beta1...
例如,我们可以创建一个切面,该切面会在方法调用前/后检查是否有`@Query`注解,并根据注解中的SQL模板执行数据库操作。 3. **动态SQL**: 使用注解拼接SQL的一个关键优点是动态性。例如,我们可以根据方法参数...
它支持CRUD(Create, Read, Update, Delete)操作,关联映射,缓存机制,以及HQL(Hibernate Query Language),使得SQL与Java对象之间的交互更加简单直观。 在"spring_Framework+经典SQL语句大全+Hibernate中文API...