我有一个使用 Spring 和 Hibernate 以及 mysql 数据库的 Web 应用程序。问题是,当应用程序启动一段时间并且长时间没有活动时,如果用户尝试登录,则会出现以下异常:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.exception.JDBCConnectionException: could not execute query
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
root cause
org.hibernate.exception.JDBCConnectionException: could not execute query
org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
org.hibernate.loader.Loader.doList(Loader.java:2231)
org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
org.hibernate.loader.Loader.list(Loader.java:2120)
org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
org.hibernate.impl.SessionImpl.list(SessionImpl.java:1596)
org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
com.smallworks.dao.impl.UserDAOImpl.getUserByLoginID(UserDAOImpl.java:102)
com.smallworks.authenticationService.impl.UserAuthenticationServiceImpl.isPasswordCorrect(UserAuthenticationServiceImpl.java:54)
com.smallworks.validation.UserLoginValidator.validate(UserLoginValidator.java:59)
com.smallworks.controller.ProjectController.signIn(ProjectController.java:84)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
root cause
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 33,781,083 milliseconds ago. The last packet sent successfully to the server was 33,781,083 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
java.lang.reflect.Constructor.newInstance(Unknown Source)
com.mysql.jdbc.Util.handleNewInstance(Util.java:407)
com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3348)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1967)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2111)
com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2273)
org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
org.hibernate.loader.Loader.doQuery(Loader.java:697
并且用户尝试再次登录,它工作正常。
以下是我的 Hibernate 的配置:
<beans>
<!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>com/smallworks/model/User.hbm.xml</value>
<value>com/smallworks/model/Contact.hbm.xml</value>
<value>com/smallworks/model/Action.hbm.xml</value>
<value>com/smallworks/model/Comment.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<!-- -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
应用程序上下文.xml
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<!-- -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- Managing connection -->
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="c3p0.testConnectionOnCheckout">false</prop>
<prop key="c3p0.min_size">5</prop>
<prop key="c3p0.max_size">50</prop>
<prop key="c3p0.timeout">300</prop>
<prop key="c3p0.max_statements">50</prop>
<prop key="c3p0.idleTestPeriod">300</prop>
</props>
</property>
我已经用上面的配置编辑了我的休眠配置,但它似乎仍然没有生效。任何正确方向的指导将不胜感激。
问候。