java.sql.SQLException:使用HikariCP [JPA + Hibernate + Guice]关闭连接

时间:2018-12-04 07:31:40

标签: java postgresql hibernate jpa hikaricp

我经常遇到此异常

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会关照的连接关闭。

任何人都可以帮忙吗?

0 个答案:

没有答案