Recently I was working on porting our application to wildfly 20 from wildfly 10 it involved upgrading hibernate to 5.3.17. We were using C3P0 connection pool in our persistence.xml. We got the following error in our logs
2020-09-11 19:28:35,785 INFO [org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator] (ServerService Thread Pool -- 86) HHH000130: Instantiating explicit connection provider: org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider
2020-09-11 19:28:35,790 INFO [org.hibernate.c3p0.internal.C3P0ConnectionProvider] (ServerService Thread Pool -- 86) HHH010002: C3P0 using driver: null at URL: null
2020-09-11 19:28:35,790 INFO [org.hibernate.c3p0.internal.C3P0ConnectionProvider] (ServerService Thread Pool -- 86) HHH10001001: Connection properties: {user=pgctools, password=****}
2020-09-11 19:28:35,790 INFO [org.hibernate.c3p0.internal.C3P0ConnectionProvider] (ServerService Thread Pool -- 86) HHH10001003: Autocommit mode: false
2020-09-11 19:28:35,791 WARN [org.hibernate.c3p0.internal.C3P0ConnectionProvider] (ServerService Thread Pool -- 86) HHH10001006: No JDBC Driver class was specified by property hibernate.connection.driver_class
2020-09-11 19:28:35,824 INFO [com.mchange.v2.log.MLog] (MLog-Init-Reporter) MLog clients using slf4j logging.
2020-09-11 19:28:35,965 INFO [com.mchange.v2.c3p0.C3P0Registry] (ServerService Thread Pool -- 86) Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
2020-09-11 19:28:36,021 INFO [org.hibernate.c3p0.internal.C3P0ConnectionProvider] (ServerService Thread Pool -- 86) HHH10001007: JDBC isolation level: <unknown>
2020-09-11 19:28:36,050 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] (ServerService Thread Pool -- 86) Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@8c1576a0 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@9df832bb [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> true, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, identityToken -> 1hge13bacyt6x751iz2mtg|5014cd2c, idleConnectionTestPeriod -> 0, initialPoolSize -> 20, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 200, maxStatements -> 50, maxStatementsPerConnection -> 0, minPoolSize -> 20, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@974ea785 [ description -> null, driverClass -> null, factoryClassLocation -> null, forceUseNamedDriverClass -> false, identityToken -> 1hge13bacyt6x751iz2mtg|5051daf8, jdbcUrl -> null, properties -> {user=******, password=******} ], preferredTestQuery -> SELECT 1;, privilegeSpawnedThreads -> false, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, extensions -> {}, factoryClassLocation -> null, identityToken -> 1hge13bacyt6x751iz2mtg|18755649, numHelperThreads -> 3 ]
2020-09-11 19:29:06,113 WARN [com.mchange.v2.resourcepool.BasicResourcePool] (C3P0PooledConnectionPoolManager[identityToken->1hge13bacyt6x751iz2mtg|18755649]-HelperThread-#2) com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@3c1f0be -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: : java.lang.NullPointerException
at org.postgresql.Driver.parseURL(Driver.java:547)
at org.postgresql.Driver.acceptsURL(Driver.java:466)
at java.sql.DriverManager.getDriver(DriverManager.java:299)
at com.mchange.v2.c3p0.DriverManagerDataSource.driver(DriverManagerDataSource.java:285)
at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
The connection pool was unable to create connection because of missing database URL and driver class. Although the database URL and driver class was configured in persistence.xml still the hibernate was not able to pick it up. I had to download hibernate code and debug it for two days to figure out the problem. Our persistence.xml looked like this:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="UnitName" transaction-type="JTA">
<properties>
<property name="jboss.as.jpa.providerModule" value="org.hibernate"/>
</properties>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/PostgresDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.session_factory_name" value="java:/jboss/SessionFactory"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/container/hibernate"/>
<property name="hibernate.current_session_context_class" value="jta" />
<property name="hibernate.connection.provider_class" value="org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/database" />
<property name="hibernate.connection.username" value="user" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.c3p0.min_size" value="20"/>
<property name="hibernate.c3p0.max_size" value="200"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_periods" value="3000"/>
<property name="hibernate.c3p0.testConnectionOnCheckin" value="true"/>
<property name="hibernate.c3p0.preferredTestQuery" value="SELECT 1;"/>
<property name="hibernate.c3p0.autoCommitOnClose" value="true"/>
</properties>
</persistence-unit>
</persistence>
The root cause of the problem was the datasource mentioned in persistence.xml file. Hibernate removes URL and database driver settings from configuration if datasource is provided in the configuration. It is because if datasource is provided then datasource will be used for getting connections so there is no use of database URL and driver class. But C3P0 connection pool required that. I removed the jta-data-source setting and it still did not work because wildfly inserted a default datasource with name ExampleDS into our persistence unit. We need to disable insertion of default data source using a wildfly specific property in persistence.xml file.
The following line needs to be inserted:
<property name="wildfly.jpa.allowdefaultdatasourceuse" value="false" />
After adding the above property C3P0 connection pool started working.
No comments:
Post a Comment