Hibernate/Spring DataSource and RDS Replica - java

I would like to setup a RDS Read Replica to forward some of the read requests to it. I've annotated all my "read" Dao methods with:
#Transactional(readOnly = true)
Now I am struggling with datasource configuration. I expected that it would be really easy, but it seems it isn't. How can I tell the datasource/hibernate that there is a read replica available on certain endpoint?
Currently my configuration looks like:
<bean id="mainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://${master-url}:3306/${db-name}?useSSL=true&requireSSL=true&verifyServerCertificate=false"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
<!-- these are C3P0 properties -->
<property name="acquireIncrement" value="3"/>
<property name="minPoolSize" value="3"/>
<property name="maxPoolSize" value="10"/>
<property name="maxIdleTime" value="3600"/>
<!-- 1 hour -->
<property name="maxConnectionAge" value="7200"/>
<property name="maxIdleTimeExcessConnections" value="600"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="testConnectionOnCheckin" value="true"/>
<property name="testConnectionOnCheckout" value="false"/>
<property name="preferredTestQuery" value="SELECT 1"/>
</bean>
<bean id="mainSessionFactory" name="mainSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" depends-on="mainDataSource">
<property name="packagesToScan">
<list>
<value>com....</value>
</list>
</property>
<property name="dataSource" ref="mainDataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.tinyInt1isBit">true</prop>
<prop key="hibernate.connection.transformedBitIsBoolean">true</prop>
<prop key="hibernate.hbm2ddl.auto">none</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.CharSet">UTF-8</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.jdbc.batch_size">40</prop>
</props>
</property>
</bean>
Any help/advice would be highly appreciated!
Best Regards,
Maksim

Related

java.sql.SQLTransientConnectionException: spring HikariCP - Connection is not available, request timed out afte

I've catched java.sql.SQLTransientConnectionException: springHikariCP - Connection is not available, request timed out after 30001ms.
First code block works well, second (CP) does not work.
What is wrong and how fix this?
JDK - 1.8.0_73.
HikariCP - 2.4.5.
Spring - 4.2.5.RELEASE.
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${connection.driverClassName}"/>
<property name="username" value="${connection.userName}"/>
<property name="password" value="${connection.password}"/>
<property name="url" value="${connection.url}"/>
</bean>
CP
<bean id="hikariConfiguration" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP"/>
<property name="dataSourceClassName" value="${connection.dataSourceClassName}"/>
<property name="maximumPoolSize" value="${connection.pool.maximumPoolSize}"/>
<property name="idleTimeout" value="${connection.pool.idleTimeout}"/>
<property name="dataSourceProperties">
<props>
<prop key="url">${connection.url}</prop>
<prop key="user">${connection.userName}</prop>
<prop key="password">${connection.password}</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy- method="close">
<constructor-arg ref="hikariConfiguration"/>
</bean>
//...............
#CONNECTION
connection.dataSourceClassName=org.hsqldb.jdbc.JDBCDataSource
connection.url=jdbc:hsqldb:mem:dbtest-local
connection.userName=sa
connection.password=
#POOL
connection.pool.maximumPoolSize=1
connection.pool.idleTimeout=28500
#HIBERNATE
hibernate.hbm2ddl.auto=create-drop
hibernate.dialect=H2Dialect
hibernate.show_sql=true
If you use the dataSourceClassName, you should not provide the jdbc url.
Instead, you should add the host, dbname, etc. as properties. See the example on github:
dataSourceClassName=org.postgresql.ds.PGSimpleDataSource
dataSource.user=test
dataSource.password=test
dataSource.databaseName=mydb
dataSource.portNumber=5432
dataSource.serverName=localhost
Otherwise, you should not use the dataSourceClassName. Try with:
<bean id="hikariConfiguration" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="maximumPoolSize" value="${connection.pool.maximumPoolSize}" />
<property name="idleTimeout" value="${connection.pool.idleTimeout}" />
<property name="jdbcUrl" value="${connection.url}" />
<property name="dataSourceProperties">
<props>
<prop key="user">${connection.userName}</prop>
<prop key="password">${connection.password}</prop>
</props>
</property>
</bean>
This is working for me in local.

connecting to databases using spring and hibernate - primary and secondary databases

Hi this is what I am looking to do -
I have three databases - each exactly the same - one is primary and two and three are back ups.
I am using hibernate and spring to connect to the data base.I have spring application context file configured with 3 session factories, and 3 corresponding data sources.
I was wondering if there is a way using spring where if the application is not able to connect to the database 1 (an exception is thrown) it will connect to database 2 - and in turn is database 3 is down it will connect to 3 and proceed.
What would be the best way to implement this? I have read about AbstractRoutingDataSource ..but not sure how to make use of that in this case..also if there are other ideas.. Would appreciate some directions. Thanks!
this is my config in application context xml -
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="$g{jdbc.driverClassName}" />
<property name="jdbcUrl" value="$g{url1}" />
<property name="user" value="$l{uid1}" />
<property name="password" value="$l{pwd1}" />
<property name="minPoolSize" value="$g{jdbc.minPoolSize}" />
<property name="maxPoolSize" value="$g{jdbc.maxPoolSize}" />
<property name="preferredTestQuery" value="$g{jdbc.preferredTestQuery}" />
<property name="testConnectionOnCheckout" value="$g{jdbc.testConnectionOnCheckout}" />
</bean>
<bean id="sessionFactory1"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">$g{jdbc.dialect}</prop>
<prop key="hibernate.show_sql">$g{jdbc.show_sql}</prop>
</props>
</property>
</bean>
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="$g{jdbc.driverClassName}" />
<property name="jdbcUrl" value="$g{url2}" />
<property name="user" value="$l{uid2}" />
<property name="password" value="$l{pwd2}" />
<property name="minPoolSize" value="$g{jdbc.minPoolSize}" />
<property name="maxPoolSize" value="$g{jdbc.maxPoolSize}" />
<property name="preferredTestQuery" value="$g{jdbc.preferredTestQuery}" />
<property name="testConnectionOnCheckout" value="$g{jdbc.testConnectionOnCheckout}" />
</bean>
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">$g{jdbc.dialect}</prop>
<prop key="hibernate.show_sql">$g{jdbc.show_sql}</prop>
</props>
</property>
</bean>
<bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="$g{jdbc.driverClassName}" />
<property name="jdbcUrl" value="$g{url3}" />
<property name="user" value="$l{uid3}" />
<property name="password" value="$l{pwd3}" />
<property name="minPoolSize" value="$g{jdbc.minPoolSize}" />
<property name="maxPoolSize" value="$g{jdbc.maxPoolSize}" />
<property name="preferredTestQuery" value="$g{jdbc.preferredTestQuery}" />
<property name="testConnectionOnCheckout" value="$g{jdbc.testConnectionOnCheckout}" />
</bean>
<bean id="sessionFactory3"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource3" />
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">$g{jdbc.dialect}</prop>
<prop key="hibernate.show_sql">$g{jdbc.show_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager1"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory1" />
</bean>
<bean id="transactionManager2"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory2" />
</bean>
<bean id="transactionManager3"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory3" />
</bean>
There is a way to achieve this by using Spring Abstract Data Source Routing mechanism -
https://spring.io/blog/2007/01/23/dynamic-datasource-routing/

Spring-Hibernate using multiple datasource/database

I'm working on a web application that uses Spring MVC 3 and Hibernate
I want to use 2 datasource MySql and Oracle databases for my web application,
I've been read many tutorial and problem solving for "spring-hibernate multiple datasource/database"
for example :
directjump2java.blogspot.com
stackoverflow
forum spring
and etc.
but when every single time I run it, the config just read my first database config (MySql)
and show this error Table 'db_prod.ksei_lookup_holiday' doesn't exist db.prod is my first database(MySql) and KSEI_LOOKUP_HOLIDAY is my second database (Oracle),
this is my spring.xml
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:annotation-driven transaction-manager="transactionManagerSOAAPP"/>
<context:annotation-config />
<context:component-scan base-package="prod.support" />
<!-- Database MySql, Desktop -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/db_prod" />
<property name="username" value="root" />
<property name="password" value="shikamaru" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"></property>
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="prod.support.model.splatter" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>
<!-- Database Oracle, Schema : SOAAPP -->
<bean id="dataSourceSOAAPP" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE" />
<property name="username" value="splatter" />
<property name="password" value="shikamaru" />
</bean>
<bean id="sessionFactorySOAAPP"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"></property>
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="prod.support.model.soaapp" />
</bean>
<bean id="transactionManagerSOAAPP"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactorySOAAPP">
</bean>
this is my DAO Implementation for my first database (MySql)
#Repository
#Qualifier(value="sessionFactory")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
#Autowired
private UserDaoImpl(SessionFactory sessionFactory){
setSessionFactory(sessionFactory);
}
this is my DAO Implementation for my second database (Oracle)
#Repository
#Qualifier(value="sessionFactorySOAAPP")
public class UpdateKSEIDaoImpl extends HibernateDaoSupport implements UpdateKSEIDao{
#Autowired
private UpdateKSEIDaoImpl(SessionFactory sessionFactorySOAAPP){
setSessionFactory(sessionFactorySOAAPP);
}
any help will be pleasure :)
The problem is that you have used
<property name="dataSource" ref="dataSource"></property> in sessionFactorySOAAPP.
You should have used <property name="dataSource" ref="dataSourceSOAAPP"></property>
If you check "sessionFactorySOAAPP" then the below property name should be 'dataSourceSOAAPP' not the 'dataSource'.
this my configuration file:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/gl?characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="2238295" />
</bean>
<bean id="mainDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/gl_main?characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="2238295" />
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="sfAccounting"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.gl.domain.accounting" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="sfCommon"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="mainDataSource" />
<property name="packagesToScan" value="com.gl.domain.common" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="txnManagerAccounting"/>
<tx:annotation-driven transaction-manager="txnManagerCommon"/>
<bean id="txnManagerAccounting"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sfAccounting" />
</bean>
<bean id="txnManagerCommon"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sfCommon" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
#geoand is correct in the error he spotted. Other than that the context xml seems correct and works for me.
However, for me, this only works if #qualifier is with the #Autowired.
#Repository
public class BusinessDaoImpl implements BusinessDao
{
#Autowired
#Qualifier(value="sessionFactory")
SessionFactory sessionFactory;

configure jta transaction manager using spring?

I have below configuration in my spring config file. I am using Spring3, Hibernate4 and Tomcat7.
<jee:jndi-lookup id="wcDataSource" jndi-name="java:comp/UserTransaction" resource-ref="false" environment-ref="remoteEnv" />
<util:properties id="remoteEnv">
<prop key="java.naming.provider.url">jnp://jndi.myURL.me:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="jnp.disableDiscovery">true</prop>
</util:properties>
<bean id="dataSourceKS" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClassName}" />
<property name="jdbcUrl" value="${url}" />
<property name="user" value="${username}" />
<property name="password" value="${password}" />
<!-- pool sizing -->
<property name="initialPoolSize" value="15" />
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="20" />
<property name="acquireIncrement" value="3" />
<property name="maxStatements" value="6000" />
<property name="maxStatementsPerConnection" value="300" />
</bean>
<bean name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceKS"/>
<property name="annotatedClasses">
<list>
<value>com.sample.MyBean</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.jdbc.batch_size">50</prop>
</props>
</property>
</bean>
Now how can i configure JTATransactionManager here to use #Transactional? Here i have wcDataSource and dataSourceKS. Thanks!
Thanks!
The JtaTransactionManager does not need to know about the DataSource, or any other specific resources, because it uses the container’s global transaction management infrastructure.
So conf file should look like this
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
See http://lafernando.com/2011/01/05/xa-transactions-with-apache-dbcp/ which does it in code but which you should be able to translate to a spring configuration.
Which would result in something like this.
<jee:jndi-lookup id="userTransaction" jndi-name="java:comp/UserTransaction" resource-ref="false" environment-ref="remoteEnv" />
<jee:jndi-lookup id="jtaTransactionManager" jndi-name="java:comp/TransactionManager" resource-ref="false" environment-ref="remoteEnv" />
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<constructor-arg ref="userTransaction"/>
<constructor-arg ref="jtaTransactionManager"/>
</bean>
<util:properties id="remoteEnv">
<prop key="java.naming.provider.url">jnp://jndi.myURL.me:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="jnp.disableDiscovery">true</prop>
</util:properties>
<bean id="oracleXaDataSource" class="oracle.jdbc.xa.client.OracleXADataSource">
<property name="user" value="${username}" />
<property name="password" value="${password}" />
<property name="url" value="${url}" />
</bean>
<bean id="dataSourceKS" class="org.apache.commons.dbcp.managed.BasicManagedDatasource">
<property name="transactionManager" ref="jtaTransactionManager" />
<property name="xaDataSourceInstance" ref="oracleXaDataSource" />
<property name="initialPoolSize" value="15" />
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="20" />
<property name="acquireIncrement" value="3" />
<property name="maxStatements" value="6000" />
<property name="maxStatementsPerConnection" value="300" />
</bean>
<bean name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="jtaDataSource" ref="dataSourceKS"/>
// .. other hibernate properties
</bean>
Note the change to commons-dbcp as c3p0 doesn't have XA capable implementations.

Where to place c3p0 properties in configuration file?

I am using spring/hibernate integrated application. i have configured c3p0 connection pooling. the problem is if i set c3p0 properties in hibernate properties section then those properties are not considered and default configuration is taken. if i set the same properties for combopooled datasource then they are considered. where is the best place to place c3p0 properties.
Below configuration works:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClassName}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
<!-- c3p0 properties -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxStatements" value="0" />
<property name="preferredTestQuery" value="select * from sometable" />
</bean>
<bean name="wygSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations" value="classpath:hibernate/module/*.hbm.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.connection.pool.size">20</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
This does not work:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClassName}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean name="wygSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations" value="classpath:hibernate/module/*.hbm.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.connection.pool.size">20</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<!-- c3p0 properties -->
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.preferredTestQuery">select * from sometable</prop>
</props>
</property>
</bean>
I was getting the same problem and it took time to figure out the solution.
I use Hibernate 4.0.1 and mysql 5.1(no spring framework) and I was facing the issue. First make sure that you configured the c3p0 jars properly which are essential.
I used these properties in hibernate.cfg.xml
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property>
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
<property name="hibernate.c3p0.idle_test_period">10</property>
<property name="hibernate.c3p0.acquireRetryAttempts">5</property>
<property name="hibernate.c3p0.acquireRetryDelay">200</property>
<property name="hibernate.c3p0.timeout">40</property>
But it's of no use 'cause C3p0 was still taking the default properties not the properties which I set in hibernate.cfg.xml, You can check it in logs. So, I searched many websites for right solution and finally I came up with this. remove the C3p0 properties in cfg.xml and create c3p0-config.xml in the root path(along with cfg.xml) and set properties as follows.
<c3p0-config>
<default-config>
<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">40</property>
<property name="idleConnectionTestPeriod">10</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
<property name="maxStatements">50</property>
<property name="preferredTestQuery">SELECT 1;</property>
<property name="acquireRetryAttempts">5</property>
<property name="acquireRetryDelay">200</property>
<property name="maxIdleTime">30</property>
</default-config>
</c3p0-config>
but if you run, ORM takes the jdbc connection but not C3p0 connection pool 'cause we should add these properties in hibernate.cfg.xml
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
now everything works fine(At least it worked fine for me) and the issue is solved.
check the following for references.
http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing
https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool
I hope this solves your problem.

Categories