原创,残梦追月转载请注明!)
使用jdbc连接数据库所有功能都没问题,发布到tomcat中也没问题,可是如果使用tomcat的数据源,来连接数据库,开始很正常,但是刷新几次就会出现这个异常……
2008-04-26 22:35:40,812 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: null
2008-04-26 22:35:40,812 ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object
2008-04-26 22:35:40,812 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: null
2008-04-26 22:35:40,812 ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object
2008-04-26 22:35:40,812 ERROR [com.dao.MessageDAO] - find all failed
org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: Cannot open connection; uncategorized SQLException for SQL [???]; SQL state [null]; error code [0]; Cannot get a connection, pool error Timeout waiting for idle object; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
Caused by:
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:104)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
……………………
开始弄了半天也不知道怎么回事,后来发现是我自己写的分页代码有问题……原来的代码如下:
2 * 自定义的,用属性模糊查询
3 *
4 * */
5 public List find(String propertyName, Object value) {
6
7 log.debug( " finding Message instance with property: " + propertyName
8
9 + " , value: " + value);
10
11 try {
12
13 String queryString = " from Message as model where model. "
14
15 + propertyName + " like " + value + " order by model.time desc " ;
16
17 return getHibernateTemplate().find(queryString);
18
19 } catch (RuntimeException re) {
20
21 log.error( " find by property name failed " , re);
22
23 throw re;
24
25 }
26
27 }
28
29
30 /**
31 *
32 * 自定义的方法,获取指定页的数据
33 *
34 * */
35 public List gotoPage( int page, int pageSize){
36
37
38
39 int totItem = this .findAll().size(); // 记录总条数
40
41 int pageNum = totItem / pageSize + 1 ; // 总页数
42
43 int begin = 0 ; // 当前起始记录数
44
45
46 begin = page * pageSize - pageSize + 1 ; // 计算当前起始位置
47
48
49 Session s = this .getSession();
50
51 String hql = " from Message message order by message.time desc " ;
52
53 Query q = s.createQuery(hql);
54
55 q.setFirstResult(begin);
56
57 q.setMaxResults(pageSize);
58
59 return q.list();
60
61 }
在这句中:
Session s =this.getSession();
String hql = "from Message message order by message.time desc";
Query q =s.createQuery(hql);
查询数据时,Spring并不能够自动管理连接,也就是说,在使用中这几句代码重视不段的获取数据库的连接,每调用一次就申请一个连接……直到 tomcat连接池中的连接耗尽……所以就再也申请不到连接了……出现了这个异常,解决办法是使用事务来管理这段代码,让Spring自动管理这段代码中申请的连接。我使用了Spring AOP自动事务代理……配置文件如下……
2 class ="org.springframework.jndi.JndiObjectFactoryBean" >
3 < property name ="jndiName" >
4 < value > java:comp/env/SqlServer </ value >
5 </ property >
6 < property name ="resourceRef" >
7 < value > true </ value >
8 </ property >
9 </ bean >
10
11 <!-- hibernate的会话工厂 -->
12 < bean id ="sessionFactory"
13 class ="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
14 < property name ="dataSource" >
15 < ref bean ="JndiDataSource" ></ ref >
16 </ property >
17 < property name ="hibernateProperties" >
18 < props >
19 < prop key ="hibernate.dialect" >
20 org.hibernate.dialect.SQLServerDialect
21 </ prop >
22 <!-- 显示SQL,为了方便测试 -->
23 < prop key ="hibernate.show_sql" > true </ prop >
24 </ props >
25 </ property >
26 < property name ="mappingResources" >
27 < list > <!-- 映射文件 -->
28 < value > ./Message.hbm.xml </ value >
29 < value > ./Setting.hbm.xml </ value >
30 < value > ./Admin.hbm.xml </ value >
31 </ list >
32 </ property >
33 </ bean >
34
35 <!-- 事务管理器 -->
36 < bean id ="transactionManger"
37 class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
38 < property name ="sessionFactory" >
39 < ref bean ="sessionFactory" />
40 </ property >
41 </ bean >
42
43 <!-- 配置事务拦截器 -->
44
45 < bean id ="transactionInterceptor"
46 class ="org.springframework.transaction.interceptor.TransactionInterceptor" >
47 < property name ="transactionManager" >
48 < ref bean ="transactionManger" />
49 </ property >
50 <!-- 下面定义事务传播属性 -->
51 < property name ="transactionAttributes" >
52 < props >
53 < prop key ="find*" > PROPAGATION_REQUIRED </ prop >
54 < prop key ="delete*" > PROPAGATION_REQUIRED </ prop >
55 < prop key ="save*" > PROPAGATION_REQUIRED </ prop >
56 < prop key ="merge*" > PROPAGATION_REQUIRED </ prop >
57 < prop key ="attach*" > PROPAGATION_REQUIRED </ prop >
58 < prop key ="gotoPage" > PROPAGATION_REQUIRED </ prop >
59 </ props >
60 </ property >
61 </ bean >
62
63 <!-- 自动代理 -->
64 < bean id ="autoBeanNameProxyCreator"
65 class ="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
66 < property name ="beanNames" >
67 < list >
68 < value > *DAO </ value >
69 < value > gotoPage </ value >
70 < value > find </ value >
71 </ list >
72 </ property >
73 < property name ="interceptorNames" >
74 < list >
75 < idref local ="transactionInterceptor" />
76 </ list >
77 </ property >
78 <!-- 这里的配置是必须的,否则无法完成代理的类型转化 这是使用CGLIB来生成代理 -->
79 < property name ="proxyTargetClass" value ="true" />
80 </ bean >
81
82 < bean id ="MessageDAO" class ="com.dao.MessageDAO" >
83 < property name ="sessionFactory" >
84 < ref bean ="sessionFactory" ></ ref >
85 </ property >
86 </ bean >
87
88 < bean id ="SettingDAO" class ="com.dao.SettingDAO" >
89 < property name ="sessionFactory" >
90 < ref bean ="sessionFactory" ></ ref >
91 </ property >
92 </ bean >
93
94 < bean id ="AdminDAO" class ="com.dao.AdminDAO" >
95 < property name ="sessionFactory" >
96 < ref bean ="sessionFactory" ></ ref >
97 </ property >
98 </ bean >