org.hibernate.exception.GenericJDBCException:无法执行查询
问题描述:
我使用hibernate 3.6.7来做映射。我将连接部分设置为静态。 我需要服务程序永远运行,另一个服务将调用此服务的一些方法来查询数据库。 当我离开服务运行的第一天,效果很好,但是当我把它的第二天,它提供了:org.hibernate.exception.GenericJDBCException:无法执行查询
org.hibernate.exception.GenericJDBCException: could not execute query
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2545)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:459)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:365)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at com.myCompany.Query.myMethod(Query.java:99)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.ebayopensource.ginger.server.internal.container.MessageProcessor.processRequest(MessageProcessor.java:93)
at org.ebayopensource.ginger.server.container.GingerServletShell.service(GingerServletShell.java:80)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:568)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.SQLException: Closed Connection
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:864)
at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:783)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:452)
at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1700)
at org.hibernate.loader.Loader.doQuery(Loader.java:801)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2542)
看来连接被关闭。 任何人都可以请给我一些建议吗?
非常感谢你:)
答
听起来要么数据库已经关闭了连接或一些网络设备已经终止了插座。有很多方法可以解决此问题:
- 您可以在连接上每隔一段时间发一些“keep alive”类型的查询(例如:SELECT 1)以保持活动状态。这假定它因为闲置而关闭。
- 您可以经常重新打开连接。
- 如果你得到一个连接关闭异常,那么你可以重新打开连接。咄。
- 您可以使用可以为您保持活动状态和重新连接的连接池。 Apache's DBCP是许多人的最爱。
我推荐最后一个。你会使用DBCP类似:
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUsername("scott");
ds.setPassword("tiger");
ds.setValidationQuery("SELECT 1"); // this is database specific
ds.setTestWhileIdle(true); // test the connections every so often
ds.setUrl(connectURI);
...
while (!shutdown) {
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
...
stmt.close();
// this returns the connection back to the pool instead of really closing
// the connection
conn.close();
}
所以不是你通过BasicDataSource
周围,并呼吁getConnection()
当你需要连接的Connection
和conn.close()
周围路过的时候,你用它做。该池执行所有的验证工作等。它还将允许多个线程使用数据库。
希望这会有所帮助。
编辑:也不能举行hibernate session开了很长一段时间。为了向您展示该会话应该是多么短暂,我将引用以下文档:
会话的生命周期受逻辑事务的开始和结束限制。 (长事务可能跨越多个数据库事务。)
会话保存数据库连接,因此您永远不想将它保留在任何时间长度。您应该执行一些数据库请求(如带查询和更新的单个Web请求),然后关闭会话,以便将基础数据库连接返回到池中。
谢谢,但我试图让一个活动的线程运行并执行查询,但它不起作用。我必须每次关闭休眠会话。只有这种方式有效。 – 2012-02-09 21:36:57
哦。我没有意识到你一直在开一个休眠会话。这是非常糟糕的形式。你应该在你的数据库通过之后关闭它,否则它将永远停留在特定的连接上。 – Gray 2012-02-09 21:48:23
我编辑了我的答案,将会话考虑在内。 – Gray 2012-02-09 23:13:36