以下是我用hibernate做的一个web应用的部分代码,appserver用的是tomcat5.5,现在的问题是应用运行一天到两天会报一个不能打开数据库连接的错误,我怀疑是数据库连接没有释放,大家帮我看看如何进行释放数据库连接数以及hibernate所申请的资源,如果需要的话我可以贴出其他代码。
1.hibernate的初始化配置hibernate.cfg.xml
/p>
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
jdbc:kingbase://172.16.205.111:54321/CMS_MUTUAL
com.kingbase.Driver
SYSTEM
SYSTEM
org.hibernate.dialect.PostgreSQLDialect
1
100
5
0
2
90
flase
thread
2.实现hibernate的工具类 HibernateUtil.java
package cn.hxex.cms.hibernate;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
/**
* 基础的Hibernate辅助类,用于Hibernate的配置和启动。
*
* 通过静态的初始化代码来读取Hibernate启动参数,并初始化
* Configuration和SessionFactory对象。
*
*
* @author galaxy
*/
public class HibernateUtil
{
private static Log log = LogFactory.getLog(HibernateUtil.class);
// 指定定义拦截器属性名
private static final String INTERCEPTOR_CLASS = "hibernate.util.interceptor_class";
// 静态Configuration和SessionFactory对象的实例(全局唯一的)
private static Configuration configuration;
private static SessionFactory sessionFactory;
static
{
// 从缺省的配置文件创建SessionFactory
try
{
// 创建默认的Configuration对象的实例
// 如果你不使用JDK 5.0或者注释请使用new Configuration()
// 来创建Configuration()对象的实例
configuration = new Configuration();
// 读取hibernate.properties或者hibernate.cfg.xml文件
configuration.configure();
// 如果在配置文件中配置了拦截器,那么将其设置到configuration对象中
String interceptorName = configuration.getProperty(INTERCEPTOR_CLASS);
if (interceptorName != null)
{
Class interceptorClass =
HibernateUtil.class.getClassLoader().loadClass(interceptorName);
Interceptor interceptor = (Interceptor)interceptorClass.newInstance();
configuration.setInterceptor(interceptor);
}
if (configuration.getProperty(Environment.SESSION_FACTORY_NAME) != null)
{
// 让Hibernate将SessionFacory绑定到JNDI
configuration.buildSessionFactory();
}
else
{
// 使用静态变量来保持SessioFactory对象的实例
sessionFactory = configuration.buildSessionFactory();
}
}
catch (Throwable ex)
{
// 输出异常信息
log.error("Building SessionFactory failed.", ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
/**
* 返回原始的Configuration对象的实例
*
* @return Configuration
*/
public static Configuration getConfiguration()
{
return configuration;
}
/**
* 返回全局的SessionFactory对象的实例
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory()
{
SessionFactory sf = null;
String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME);
if ( sfName != null)
{
log.debug("Looking up SessionFactory in JNDI.");
try
{
sf = (SessionFactory) new InitialContext().lookup(sfName);
}
catch (NamingException ex)
{
throw new RuntimeException(ex);
}
}
else
{
sf = sessionFactory;
}
if (sf == null)
throw new IllegalStateException( "SessionFactory not available." );
return sf;
}
/**
* 关闭当前的SessionFactory并且释放所有的资源
*/
public static void shutdown()
{
log.debug("Shutting down Hibernate.");
// Close caches and connection pools
getSessionFactory().close();
// Clear static variables
configuration = null;
sessionFactory = null;
}
/**
* 使用静态的Configuration对象来重新构建SessionFactory。
*/
public static void rebuildSessionFactory()
{
log.debug("Using current Configuration for rebuild.");
rebuildSessionFactory(configuration);
}
/**
* 使用指定的Configuration对象来重新构建SessionFactory对象。
*
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg)
{
log.debug("Rebuilding the SessionFactory from given Configuration.");
synchronized(sessionFactory)
{
if (sessionFactory != null && !sessionFactory.isClosed())
sessionFactory.close();
if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null)
cfg.buildSessionFactory();
else
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
}
}
/**
* 在当前SessionFactory中注册一个拦截器
*/
public static SessionFactory registerInterceptorAndRebuild(Interceptor interceptor)
{
log.debug("Setting new global Hibernate interceptor and restarting.");
configuration.setInterceptor(interceptor);
rebuildSessionFactory();
return getSessionFactory();
}
/**
* 获得拦截器对象
*
* @return Interceptor
*/
public static Interceptor getInterceptor()
{
return configuration.getInterceptor();
}
/**
* 提交当前事务,并开始一个新的事务
*/
public static void commitAndBeginTransaction()
{
sessionFactory.getCurrentSession().getTransaction().commit();
sessionFactory.getCurrentSession().beginTransaction();
}
}
3.通过滤器实现hibernate的事务管理
package cn.hxex.cms.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import cn.hxex.cms.hibernate.HibernateUtil;
/**
* 用于进行Hibernate事务处理的Servlet过滤器
*
* @author galaxy
*/
public class HibernateFilter implements Filter {
private static Log log = LogFactory.getLog(HibernateFilter.class);
/**
* 过滤器的主要方法
* 用于实现Hibernate事务的开始和提交
*/
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
// 得到SessionFactory对象的实例
SessionFactory sf = HibernateUtil.getSessionFactory();
try
{
// 开始一个新的事务
log.debug("Starting a database transaction");
sf.getCurrentSession().beginTransaction();
log.debug( "Request Path:\t" + ((HttpServletRequest)request).getServletPath() );
// Call the next filter (continue request processing)
chain.doFilter(request, response);
// 提交事务
log.debug("Committing the database transaction");
sf.getCurrentSession().getTransaction().commit();
}
catch (Throwable ex)
{
ex.printStackTrace();
try
{
// 回滚事务
log.debug("Trying to rollback database transaction after exception");
sf.getCurrentSession().getTransaction().rollback();
}
catch (Throwable rbEx)
{
log.error("Could not rollback transaction after exception!", rbEx);
}
// 抛出异常
throw new ServletException(ex);
}
}
/**
* Servlet过滤器的初始化方法
* 可以读取配置文件中设置的配置参数
*/
public void init(FilterConfig filterConfig) throws ServletException {}
/**
* Servlet的销毁方法
* 用于释放过滤器所申请的资源
*/
public void destroy() {
}
}
4.定义DAO接口并进行实现
package cn.hxex.cms.dao1;
import java.io.IOException;
import java.util.List;
import cn.hxex.cms.model.Channel;
import javax.servlet.jsp.JspWriter;
public interface IFunctionDAO {
public List getid(String code);
public List getPage(String code,String condition,String theOrder,int firstResults,int maxResult);
public String getPageCount(String code,String condition,int maxResults);
public String getTotalMark(String code,String condition);
public List getjiaohuPage(String tb_name,String condition,String theOrder,int firstResults,int maxResult);
public String getjiaohuPageCount(String tb_name,String condition,int maxResults);
public String getjiaohuTotalMark(String tb_name,String condition);
public int SetNums(String id);//根据一条id 记录浏览次数
public List getNews(String code,String condition,String theOrder,int firstResults,int maxResult);
public List getids(String code);
public String getPageCount1(String code,String condition,int maxResults);
public String getTotalMark1(String code,String condition);
public String snatch(String web_url, String coding, String file) throws IOException;
public List getContent(String id);
}
5.DAOFactory的实现
package cn.hxex.cms.dao1;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;
import cn.hxex.cms.config.CmsConfig;
/**
* DAO工厂类还负责读取配置文件
*/
public class DaoFactory {
private static Log log = LogFactory.getLog(DaoFactory.class);
// 全局的配置信息对象
public static final CmsConfig cmsConfig;
// 进行XML文件向Java对象的转换
static
{
Digester digester = new Digester();
digester.setValidating( false );
// 设置处理规则
digester.addObjectCreate( "config",
"cn.hxex.cms.config.CmsConfig" );
digester.addSetProperties( "config" );
digester.addObjectCreate( "config/dao",
"cn.hxex.cms.config.DaoConfig" );
digester.addSetProperties( "config/dao" );
digester.addSetNext( "config/dao", "addDao",
"cn.hxex.cms.config.DaoConfig" );
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
InputStream in =
classLoader.getResourceAsStream( "CmsConfig.xml" );
CmsConfig config = null;
try
{
if( in!=null )
config = (CmsConfig)digester.parse( in );
}
catch (IOException e)
{
e.printStackTrace();
}
catch (SAXException e)
{
e.printStackTrace();
}
cmsConfig = config;
}
// 取得Dao的实例
public static Object getDao( String name )
{
if( null==cmsConfig ) return null;
if( log.isInfoEnabled() ) {
log.info( "Getting the dao:" + name );
}
return cmsConfig.getDao( name );
}
public static ISysMenuDAO getSysMenuDAO() {
log.info( "Getting the sysMenuDAO..." );
return (ISysMenuDAO)getDao( "SysMenuDAO" );
}
public static ISysUsersDAO getSysUsersDAO() {
log.info( "Getting the SysUsersDAO..." );
return (ISysUsersDAO)getDao( "SysUsersDAO" );
}
public static INewsChannelDAO getNewsChannelDAO() {
log.info( "Getting the NewsChannelDAO..." );
return (INewsChannelDAO)getDao( "NewsChannelDAO" );
}
public static ISysNewsDAO getSysNewsDAO() {
log.info( "Getting the SysNewsDAO..." );
return (ISysNewsDAO)getDao( "SysNewsDAO" );
}
public static IWarterMarkDAO getWARTERMARKDAO() {
log.info( "Getting the WARTERMARKDAO..." );
return (IWarterMarkDAO)getDao( "WARTERMARKDAO" );
}
public static ISysCommentDAO getSysCommentDAO() {
log.info( "Getting the SysCommentDAO..." );
return (ISysCommentDAO)getDao( "SysCommentDAO" );
}
public static IFunctionDAO getFunctionDAO() {
log.info( "Getting the functionDAO..." );
return (IFunctionDAO)getDao( "functionDAO" );
}
public static IParameterDao getParameterDao() {
log.info( "Getting the ParameterDA..." );
return (IParameterDao)getDao( "ParameterDAO" );
}
public static IVoteDAO getVoteDAO() {
log.info( "Getting the VoteDAO..." );
return (IVoteDAO)getDao( "VoteDAO" );
}
}
6.前台显示用jsp调用DAO接口进行数据显示
问题补充
c3p0的连接池已经用到了。
1
100
5
0
2
90
问题补充
连接池是用的c3p0。
如果使用的是getCurrentSession来创建session的话,在commit后,session就自动被关闭了,也就是不用再session.close()了。但是如果使用的是openSession方法创建的session的话,那么必须显示的关闭session,也就是调用session.close()方法。这样commit后,session并没有关闭.
不知道上边的说的对不,如果是那样的话,我的这个就应该是自己释放了,因为我用的是getCurrentSession来创建session.