J'ai déployé une application GWT sur un serveur Tomcat. Tout fonctionne bien mais parfois j'obtiens l'exception suivante:
org.hibernate.exception.JDBCConnectionException: could not extract ResultSet
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.Java:389)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.Java:579)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.Java:265)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.Java:305)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.Java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:644)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:725)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:301)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
at org.Apache.Tomcat.websocket.server.WsFilter.doFilter(WsFilter.Java:52)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:219)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:106)
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:503)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:136)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:74)
at org.Apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.Java:610)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:88)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:526)
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1017)
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:652)
at org.Apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.Java:222)
at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.Java:1575)
at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.Java:1533)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617)
at Java.lang.Thread.run(Thread.Java:744)
Caused by: org.hibernate.exception.JDBCConnectionException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.Java:132)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.Java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:110)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.Java:61)
at org.hibernate.loader.Loader.getResultSet(Loader.Java:2040)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.Java:1837)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.Java:1816)
at org.hibernate.loader.Loader.doQuery(Loader.Java:900)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.Java:342)
at org.hibernate.loader.Loader.doList(Loader.Java:2526)
at org.hibernate.loader.Loader.doList(Loader.Java:2512)
Comme vous pouvez le voir, j'utilise Hibernate pour gérer ma base de données avec la configuration suivante:
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://server:3306/db</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">15</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<!-- SQL dialect -->
<property name="dialect">com.ohapp.webtattoon.server.service.Mysql5BitBooleanDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">validate</property>
Je ne sais pas pourquoi cela se produit. J'apprécierais volontiers de l'aide.
Je vous remercie
j.s m'a pointé dans la bonne direction mais n'a pas résolu mon problème.
Donc, sur la base de la réponse donnée par j.s, j'ai changé ma configuration de mise en veille prolongée en:
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://server:3306/db?autoReconnect=true</property>
<property name="connection.username">user</property>
<property name="connection.password">password</property>
<!-- C3P0 connection pool -->
<property name="hibernate.c3p0.timeout">600</property>
<property name="hibernate.c3p0.maxIdleTimeExcessConnections">20</property>
<!-- Connection testing settings -->
<property name="hibernate.c3p0.validate">false</property>
<property name="hibernate.c3p0.idle_test_period">30</property>
<property name="hibernate.c3p0.automaticTestTable">conTestTable</property>
<!-- SQL dialect -->
<property name="dialect">com.ohapp.webtattoon.server.service.Mysql5BitBooleanDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">validate</property>
La principale différence réside dans les propriétés "hibernate.c3p0.idle_test_period" et "hibernate.c3p0.automaticTestTable". Une configuration qui garantit que les connexions de mon pool sont toujours valides, empêchant les erreurs d'utiliser des connexions mortes.
Il semble que la configuration du pool de connexions soit incomplète. Le délai d'expiration des connexions est défini sur 300 s.
<property name="hibernate.c3p0.timeout">300</property>
Par conséquent, une connexion peut devenir invalide. Ces connexions non valides ne sont pas supprimées du pool de connexions jusqu'à ce que vous spécifiiez une règle sur ce qu'il faut faire avec ces connexions.
En ajoutant la ligne suivante, un test de connexion est effectué à chaque extraction de connexion pour vérifier que la connexion est valide:
<property name="hibernate.c3p0.testConnectionOnCheckout" value="true" />
Plus d'informations sur les tests de connexion: test de connexion c3p
Edit : Il existe une autre propriété très importante, qui n'est pas présente dans votre configuration:
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
Sans cette propriété, c3p0 n'est pas utilisé du tout. Sry, que je n'ai pas vu ça.