Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1147504
  • 博文数量: 234
  • 博客积分: 5592
  • 博客等级: 大校
  • 技术积分: 1987
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 14:12
文章分类

全部博文(234)

文章存档

2015年(1)

2013年(4)

2012年(16)

2011年(204)

2010年(9)

分类: Java

2011-06-16 16:51:09

转载于:http://lin5061.javaeye.com/blog/88289

 

使用Hibernate時,大家一般都記住了配置基本的那些選項,比如方言, 緩存等,但是有一項配置卻很容易忘掉,這就是連接釋放模式:hibernate.connection.release_mode,可有三個選 擇,after_statement/after_transaction/on_close,javadoc中可以看出它們的用處,這裡不再講,注意的 一點是,如果不配置的話默認是on_close,那麼如果沒有顯示的去調用session.close或其它關閉連接的方法的話,這個連接是不會被關閉 的!在用到連接池的時候,這就更體現出問題了:池中的連接會一直存在著而不會被關閉和回收!
  從log4j打印出來的日志也可以看出來,如果是on_close模式,則:
transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
  具體的一些細節可以看看hibernate的源代碼,涉及到的兩個類為:
  org.hibernate.ConnectionReleaseMode
  org.hibernate.jdbc.ConnectionManager

 

  最後,貼一下配置的代碼:
  after_transaction

=========================================

转载于 :http://blog.myspace.cn/e/404057125.htm

 最近在做项目时遇到一个问题,程序框架用的是Spring + Hibernate + Struts,当对数据库进行操作时,程序在运行几次之后,就会再无反应,浏览器的进度条也停在中间不走了,看控制台也并没有报任何异常,最后在日志中找出了点东东,还算有用,日志输出下面这句后就停止了,程序就执行到此了。

[org.hibernate.jdbc.ConnectionManager]-[DEBUG] opening JDBC connection

明显是数据库连接问题,向上翻看日志,发现数据库连接没有释放。源文件如下:

public class OrdersDao extends HibernateDaoSupport {      //方式一

         /*

          * 查询订单

          */

         public List getAllOrders() {

                   String hql = "From Orders ";

                   Query query = super.getSession().createQuery(hql);

                   return query.list();

         }

}

后来上网查了资料,说是session没有关闭,也就是连接没有释放,所以,我就改成了如下代码:

public class OrdersDao extends HibernateDaoSupport {

         /*

          * 查询订单

          */

public List getAllOrders() {

         Session session = null;

                   try {

                            session = super.getSession();

                            String hql = "From Orders ";

                            Query query = session.createQuery(hql);

                            return query.list();

                   } catch (Exception e) {

                            e.printStackTrace();

                            return null;

                   }finally{

                            session.clear();

                            session.close();

                   }

}

问题解决了。

不过,在网上查到的资料中,有的人同样是这样关闭了session,可问题却依旧存在,在随后我同样这样修改另一个项目中的源码时,运行后问题也是依旧存在,没有解决,我就依次查看日志,发现因为我在项目用了Hibernate的关联映射,在查询加载数据时对其它实体对象也进地了加载,而没有全部修改,这时我把其它所有关联的查询的session都关闭,再次部署运行后,问题就不复存在了。

这种问题还有一种解决方式就是用 Spring 方式的编码进行实现。代码如下:

public class OrdersDao extends HibernateDaoSupport {      //方式二

         /*

          * 查询订单

          */

         public List getAllOrders() {

                   return getHibernateTemplate().executeFind(new HibernateCallback() {

                      public Object doInHibernate(Session session) throws HibernateException,SQLException {

                       Query query = session.createQuery("From Orders ");

                       List list = query.list();

                       return list;

                      }

                     }

                   );

         }

 

采用这样的编码,问题也能解决。

这就要说一下方式一和方式二这两种方法的区别了。这两种方式的区别就是对Session的控制,方式一中写法要自己控制Session的释放,而方式二的写法刚由Spring的模板类控制Session,把Session的控制问题全抛给模板处理了。这样看来,要在Spring下做开发,方式二的方法会好些,但是,方式二的写法有些怪异,并且麻烦,所有我个人还是喜欢方式一中 的写法,简洁明朗。

如果有人喜欢Spring风格的编码,我在网上查资料时发现了一份别人打包好的Spring风格编码,简化了这种编码方式。代码如下:

Spring的处理方式

Spring用回调HibernateCallBack方法实现持久层一些功能,当这些功能不能满足需求时,我们也可以自已来重写HibernateCallBack,:

package com.notepad.comm;

import java.sql.SQLException;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.springframework.orm.hibernate3.HibernateCallback;

public class HQLCallBackUtil implements HibernateCallback {

private String hql;

 

public HQLCallBackUtil(){

 

}

 

public HQLCallBackUtil(String hql){

  this.hql=hql;

}

public String getHql() {

  return hql;

}

public void setHql(String hql) {

  this.hql = hql;

}

public Object doInHibernate(Session s) throws HibernateException,

   SQLException {

  if (hql == null || hql.equals("")) {

   throw new HibernateException("Can't execute NULL hql!");

  }

  return s.createQuery(hql).list();

}

}

然后可以通过如下代码进行调用

public class UsersDAO extends HibernateDaoSupport {

   ......

public List getUsers() {

     HQLCallBackUtil callBack=new HQLCallBackUtil();

     callBack.setHql("From Users AS user ORDER BY user.username DESC");

     return this.getHibernateTemplate().executeFind(callBack);

}

  ......

}

这样是不是感觉简单很多呢!

阅读(6360) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~