我经常遇到此异常:
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:147)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1423)
at org.hibernate.query.Query.getResultList(Query.java:146)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:72)
at com.inmobi.programmatics.myservice.dao.impl.AbstractDAOImpl.getByIds(AbstractDAOImpl.java:117)
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:182)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1940)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1909)
Caused by: java.sql.SQLException: Connection is closed
at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection$1.invoke(ProxyConnection.java:469)
at com.sun.proxy.$Proxy66.prepareStatement(Unknown Source)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:310)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
这是我将HikariCP与JPA Hibernate一起使用的配置:
JpaPersistModule jpaPersistModule = new JpaPersistModule("persistenceConfig");
final Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.hikari.dataSource.url",
"jdbc:postgresql://" + configurationData.getDBHost() + ":" + configurationData.getDBPort()
+ "/" + configurationData.getDBName() + "?stringtype=unspecified");
properties.put("hibernate.hikari.dataSource.user", configurationData.getDBUser());
properties.put("hibernate.hikari.dataSource.password", configurationData.getDBPassword());
properties.put("hibernate.hikari.minimumIdle", "2");
properties.put("hibernate.hikari.maximumPoolSize", "8");
properties.put("hibernate.hikari.connectionTimeout", "30000");
properties.put("hibernate.hikari.idleTimeout", "60000");
properties.put("hibernate.hikari.poolName", "master_pool");
properties.put("hibernate.hikari.leakDetectionThreshold", "60000");
properties.put("hibernate.hikari.maxLifetime", "600000");
properties.put("hibernate.hikari.connectionTestQuery", "select 1");
properties.put("hibernate.hikari.connectionInitSql", "select 1");
这是我用于JPA的peristence.xml:
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="persistenceConfig" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL94Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.jdbc.time_zone" value="UTC"/>
<property name="hibernate.jdbc.batch_size" value="25"/>
<property name="hibernate.connection.provider_class" value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider"/>
<property name="hibernate.hikari.dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource"/>
</properties>
</persistence-unit>
</persistence>
我已检查postgres db中的idle_in_transaction_session_timeout为1小时。这意味着从数据库方面来看没有问题。
我试图调整hikaricp配置。但这没有帮助。
最初,我认为可能是因为泄漏连接,为此我将 leakDetectionThreshold 添加到60秒。
然后我再次认为这可能是因为从设置了 connectionTestQuery 的池中获得了无效的连接。但这也无济于事。
我已经检查到最大有1或2个连接随时处于活动状态。因此,这不会是maxpool大小的问题。
我已经研究了这个stackoverflow question。我的问题陈述没有任何意义,因为我在Guice Transactional中使用了entitymanager。因此,我不必担心Guice Transactional会关照的连接关闭。
任何人都可以帮忙吗?