By default, Hibernate uses JDBC connections in order to interact with a database. Creating these connections is expensive, probably the most expensive, single operation Hibernate will execute in a typical usecase. For this reason, we are advised to use a connection pool, which can store open connections ahead of time and close them only when they are not needed.
C3P0 is an example of an external connection pool. In this tutorial, we will learn using C3P0 with hibernate.
Table of Contents 1. Maven dependencies 2. Configure C3P0 Connection Pool with Hibernate 3. Debug connection leaks 3. Test connection pooling in runtime
1. Maven dependencies
To configure c3p0 with hibernate, we need to add c3p0 and Hibernate’s c3p0 connection provider hibernate-c3p0 as dependencies in the pom.xml
.
Please note that the version of the hibernate-c3p0
dependency should match the Hibernate’s compatible version.
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.4.17.Final</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.3</version> </dependency>
2. Configuring C3P0 with Hibernate
The best part is that the configuration of C3P0 with hibernate is really very easy. Just add any c3p0 property inside the hibernate.cfg.xml
file and that’s it.
<property name="hibernate.c3p0.min_size">10</property>
Congratulations !! Connection pooling with C3P0 is now configured with the application’s hibernate layer. We are good to start testing the things. Really easy, Isn’t it?
A rather detailed configuration can be setup using following properties in hibernate.cfg.xml
. All keys are prefixed with hibernate.c3p0
.
<property name="hibernate.c3p0.min_size">10</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.acquire_increment">1</property> <property name="hibernate.c3p0.idle_test_period">3000</property> <property name="hibernate.c3p0.max_statements">50</property> <property name="hibernate.c3p0.timeout">1800</property> <property name="hibernate.c3p0.validate">1800</property>
We can find detailed information about about above configuration switches in official documentation.
3. Debug connection leaks
Sometimes applications talk to many other applications and some applications or interactions take a longer time to respond. This can overwhelm the connection pool (when the pool grows to maxPoolSize
) and degrade the performance of the whole application.
c3p0 can help us debug the pool where connections have been checked out and don’t get checked in.
<property name="hibernate.c3p0.unreturnedConnectionTimeout">30</property> <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces">true</property>
unreturnedConnectionTimeout
helps in fixing leaks. It defines time (in seconds) to how long a Connection may remain checked out. Checked-out Connections that exceed this limit will be destroyed, and then created a new one in the pool.
debugUnreturnedConnectionStackTraces
helps in debugging the root cause. when set to true
, whenever an unreturned Connection times out, that stack trace will be printed, revealing where a Connection was checked out that was not checked in.
4. Testing connection pool in runtime
4.1. Without C3P0 Connection Pool Configuration
Without C3P0 configured, if you see the debug logs of hibernate, you will see something like this:
DEBUG Configuration:1841 - Preparing to build session factory with filters : {} WARN DriverManagerConnectionProviderImpl:93 - HHH000402: Using Hibernate built-in connection pool (not for production use!) INFO DriverManagerConnectionProviderImpl:166 - HHH000401: using driver [org.hsqldb.jdbcDriver] at URL [jdbc:hsqldb:mem:howtodoinjava] INFO DriverManagerConnectionProviderImpl:172 - HHH000046: Connection properties: {user=sa, password=} INFO DriverManagerConnectionProviderImpl:180 - HHH000006: Autocommit mode: false INFO DriverManagerConnectionProviderImpl:102 - HHH000115: Hibernate connection pool size: 20 (min=1) DEBUG DriverManagerConnectionProviderImpl:104 - Initializing Connection pool with 1 Connections ... ... ... EBUG JdbcTransaction:113 - committed JDBC Connection DEBUG SessionFactoryImpl:1339 - HHH000031: Closing DEBUG AbstractServiceRegistryImpl:406 - Implicitly destroying ServiceRegistry on de-registration of all child ServiceRegistries INFO DriverManagerConnectionProviderImpl:281 - HHH000030: Cleaning up connection pool [jdbc:hsqldb:mem:howtodoinjava]
4.2. Using C3P0 Connection Pool Configuration
After configuring C3P0 Connection Pool, you will be able to see in the logs that connections are now acquired from C3P0 Connection Pool itself.
DEBUG Configuration:1841 - Preparing to build session factory with filters : {} INFO C3P0ConnectionProvider:133 - HHH010002: C3P0 using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:mem:howtodoinjava INFO C3P0ConnectionProvider:134 - HHH000046: Connection properties: {user=sa, password=****} INFO C3P0ConnectionProvider:137 - HHH000006: Autocommit mode: false INFO MLog:92 - MLog clients using log4j logging. INFO C3P0Registry:216 - Initializing c3p0-0.9.2.1 [built 20-March-2013 10:47:27 +0000; debug? true; trace: 10] DEBUG DynamicPooledDataSourceManagerMBean:258 - MBean: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=19tu9of94ho8s13xij3fm|34e475e1,name=19tu9of94ho8s13xij3fm|34e475e1 registered. DEBUG DynamicPooledDataSourceManagerMBean:253 - MBean: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=19tu9of94ho8s13xij3fm|34e475e1,name=19tu9of94ho8s13xij3fm|34e475e1 unregistered, in order to be reregistered after update. DEBUG DynamicPooledDataSourceManagerMBean:258 - MBean: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=19tu9of94ho8s13xij3fm|34e475e1,name=19tu9of94ho8s13xij3fm|34e475e1 registered. INFO AbstractPoolBackedDataSource:522 - Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@d29bbf50 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@a9bbd924 [ ... ] ... ... ... DEBUG ActiveManagementCoordinator:97 - C3P0Registry mbean unregistered. DEBUG BasicResourcePool:1022 - Preparing to destroy resource: com.mchange.v2.c3p0.impl.NewPooledConnection@1d1fcfbb DEBUG C3P0PooledConnectionPool:616 - Preparing to destroy PooledConnection: com.mchange.v2.c3p0.impl.NewPooledConnection@1d1fcfbb DEBUG AbstractPoolBackedDataSource:477 - com.mchange.v2.c3p0.PoolBackedDataSource@34e475e1 has been closed. java.lang.Exception: DEBUG STACK TRACE for PoolBackedDataSource.close(). at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.close(AbstractPoolBackedDataSource.java:477) at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.close(AbstractPoolBackedDataSource.java:489) at com.mchange.v2.c3p0.DataSources.destroy(DataSources.java:372) at com.mchange.v2.c3p0.DataSources.destroy(DataSources.java:348) at org.hibernate.c3p0.internal.C3P0ConnectionProvider.stop(C3P0ConnectionProvider.java:258) at org.hibernate.service.internal.AbstractServiceRegistryImpl.stopService(AbstractServiceRegistryImpl.java:377) at org.hibernate.service.internal.AbstractServiceRegistryImpl.destroy(AbstractServiceRegistryImpl.java:361) at org.hibernate.service.internal.AbstractServiceRegistryImpl.deRegisterChild(AbstractServiceRegistryImpl.java:410) at org.hibernate.service.internal.AbstractServiceRegistryImpl.destroy(AbstractServiceRegistryImpl.java:368) at org.hibernate.internal.SessionFactoryImpl.close(SessionFactoryImpl.java:1377) at com.howtodoinjava.demo.util.HibernateUtil.shutdown(HibernateUtil.java:39) at com.howtodoinjava.test.TestHibernate.main(TestHibernate.java:22)
That’s all for this easy but useful tutorial about configuring C3P0 Connection Pool with hibernate.
Happy Learning !!
Reference: http://www.mchange.com/projects/c3p0/#configuration
Subhajit Kar
Hi
I have configured c3p0 with Hibernate. It works fine till connections get exhausted to max limit. Then it stops providing responses. So, practically, my web app does not receive any data. No errors in console.
Tried with “org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider” also.
My sessionFactory creation class is as below:
I have done
session.flush()
andsession.close()
after every DB queries.It seems that the connection is not released from the pool for another client to use. Hence after the max number of connections is reached, it is waiting for one to be released, which is not happening.
I tried with 50 as max limit, it stays for longer than stops.
Am I missing something?
Lokesh Gupta
Please share your persistence.xml/hibernate-cfg.xml after masking any sensitive data.
Dirk
Is it possible to modify all properties at runtime? For instance, if I encounter that the value of maximum connections needs to be increased, can I do this without re-starting the CP?
partha
sir if am creating a connection pool in tomcat with c3p0 then how to use it in hibernate
Lokesh Gupta
As mentioned in post, all you need to do is define any property in hibernate config file starting with “hibernate.c3p0.”. Then hibernate will take care of everything in backend.