c3p0 connection pooling properties are not set? - java

I am using spring/hibernate application and configured c3p0 connection pooling. c3p0 connection pooling is enabled. i verified my logs.
10 May 2012 14:55:56 INFO AbstractPoolBackedDataSource:462 - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource
But the problem is, programmatically i am getting configured datasource and tried to see its properties but what ever properties i set in configuration file, they are not set. Please find below configuration and debugged values.
<prop key="hibernate.connection.pool.size">20</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.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<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">50</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
<prop key="hibernate.jdbc.batch_size">50</prop>
<prop key="hibernate.c3p0.preferredTestQuery">SELECT GETDATE()</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">true</prop>
debugged values:
i am getting datasource as below.
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
.......getBean("datasourceId");
..................
in properties i set preferred test query. that is also null in the image.
am i missing any thing here. Thanks!

I use it as follows
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="pooledConn"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect" >${HIBERNATE.DIALECT}</prop>
<!-- <prop key="hibernate.show_sql">${HIBERNATE.SHOW_SQL}</prop> -->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">${HIBERNATE.hBM2DDL.AUTO}</prop>
</props>
</property>
and it works absolutely perfect for me , could you please paste your config for more help

Try to add the following to your configuration file:
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>

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.

Related

How to configure Hibernate, Spring and Apache dbcp for connection pooling?

I have a problem integrating Spring, Hibernate, and Apache DBCP. I have used the DBCPConnectionProvider from here.
I have the following xml configuration for the above said.
<context:component-scan base-package="com.my.app"/>
<tx:annotation-driven/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>com.my.app.model</value>
</list>
</property>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/app</prop>
<prop key="hibernate.connection.username">foo</prop>
<prop key="hibernate.connection.password">bar</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.DBCPConnectionProvider</prop>
<!-- Connection pooling related properties -->
<prop key="hibernate.dbcp.initialSize">8</prop>
<prop key="hibernate.dbcp.maxActive">20</prop>
<prop key="hibernate.dbcp.maxIdle">5</prop>
<prop key="hibernate.dbcp.minIdle">0</prop>
<prop key="hibernate.dbcp.maxWait">10000</prop>
<prop key="hibernate.dbcp.minEvictableIdleTimeMillis">180000</prop>
<prop key="hibernate.dbcp.timeBetweenEvictionRunsMillis">180000</prop>
<prop key="hibernate.dbcp.testWhileIdle">true</prop>
<prop key="hibernate.dbcp.testOnReturn">true</prop>
<prop key="hibernate.dbcp.validationQuery">select 1</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
When the database schema i.e. app is empty two tables will be created in mysql. But I am getting NullPointerException in the getConnection() method of the DBCPConnectionProvider that I mentioned. That means the dataSource is not instantiated. I think I have configured everything in the xml. What am I missing. How do you configure DBCP version 1.4 with Spring and Hibernate? Please provide your insights.
Here is the stack trace:
Caused by: java.lang.NullPointerException
at org.hibernate.connection.DBCPConnectionProvider.getConnection(DBCPConnectionProvider.java:209)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:417)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:119)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:57)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1326)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
... 82 more
Don't do it like that. Configure the datasource you want to use in Spring as well as Hibernate. Ditch the hibernate.dbcp and hibernate.connection properties.
<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/app"/>
<property name="username" value="foo"/>
<property name="password" value="bar"/>
// Other DBCP properties here
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"
<property name="packagesToScan">
<list>
<value>com.my.app.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
Just add the dataSource property to your AnnotationSessionFactoryBean as dependency and done. Note you don't need the configurationClass property as it is already annotation based.
A tip I wouldn't suggest using Commons-DBCP anymore as a datasource instead take a look at HikariCP as a better datasource implementation.
For more information in integrating/configuring Hibernate with Spring I suggest this section of the Reference Guide.

hibernate create schema if not exists mysql

I'm using Spring 3 and hibernate 4.
Here is my root-context.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/musicstore"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="sessionFactory" name="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan" value="domain" /><!--
entity -->
</bean>
And I've got this :
WARN : org.hibernate.engine.jdbc.internal.JdbcServicesImpl - HHH000342: Could not obtain connection to query metadata : Unknown database 'musicstore'
When I deploy my project in tomcat, I want hibernate will create the schema if it's not exist. I have tried hibernate.hbm2ddl.auto= create but it's not working
Are there any ways to do create the schema automatically at run time ? Any suggestions would be helpful :D
Thanks in advance.
I don't know how to solve your problem in a hibernate specific way, but a cool thing about MySQL is that you can (at the very least under certain conditions) specify for the Database itself to be created if it doesn't already exist via the connection string by appending "?createDatabaseIfNotExist=true" to the end.
So, by changing your Spring config to the following you should get the results you need.
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/musicstore?createDatabaseIfNotExist=true"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="sessionFactory" name="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan" value="domain" /><!--
entity -->
</bean>
It's worth noting that I don't know anything more about this than that it works, so it may very well have limitations of which I am unaware.
Hibernate requires the database to exist: it cannot help you create the database. If you need to create the database the you will need to implement another solution that executes before Hibernate is initialized.
As you are using Spring the following may be useful for executing the initial 'CREATE DATABASE X' statement.
http://docs.spring.io/spring-framework/docs/3.0.0.RC3/reference/html/ch12s09.html
You obviously need to ensure the initailization executes before the sessionFactory bean is initialized.
You would also likely define 2 datasources, one configured as outlined at the link provided by mretierer (Create MySQL database from Java) i.e. with no database defined and which is used by the Spring db initializer bean and one for use by Hibernate which references the database created during initialization.
No idea if any of this will work but looks feasible...
First the answer to your question: The property you already supplied should do what you were asking for.
<prop key="hibernate.hbm2ddl.auto">update</prop>
The exception your are getting refers to a different problem. Hibernate can't connect to the database you specified.
Pls check your connection string
<property name="url" value="jdbc:mysql://localhost:3306/musicstore"></property>

hibernate3.LocalDataSourceConnectionProvider cannot be cast to ConnectionProvider

2.4release , hibernate 3.3.2ga . while creating sessionfactory. I'm getting following error. Please provide me a solution
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="erpUSDataSource" />
<property name="annotatedClasses">
<list>
<value>com.bean.OrderDetailsVO</value>
<value>com.bean.OrderVO</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
<!-- <prop key="hibernate.use_outer_join">false</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
<prop key="hibernate.hibernate.cache.use_query_cache">true</prop> -->
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
Caused by: org.hibernate.HibernateException: Could not instantiate connection provider [org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider]
at org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:192) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
at org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:114) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
at org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:54) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
at org.hibernate.service.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:69) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:176) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
... 90 more
Caused by: java.lang.ClassCastException: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider cannot be cast to org.hibernate.service.jdbc.connections.spi.ConnectionProvider
at org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:189) [hibernate-core-4.2.0.Final-redhat-1.jar:4.2.0.Final-redhat-1]
... 94 more
Judging from the stacktrace you are deploying on a newer JBoss server which comes, by default, shipped with hibernate4 as such hibernate3 classes aren't going to work.
Either you have to include your own hibernate library into your war file to use hibernate3 (and you probably will have to fix several other classloading issues then). Or you switch to use Hibernate4.
When using hibernate4 there is no more HibernateTemplate (as that should be considered deprecated since the release of hibernate 3.0.1 in 2006!). You might have to change some of your code if you rely heavily on the HibernateTemplate.
For your configuration simply switch to the hibernate4 class.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="erpUSDataSource" />
<property name="annotatedClasses">
<list>
<value>com.bean.OrderDetailsVO</value>
<value>com.bean.OrderVO</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
<!-- <prop key="hibernate.use_outer_join">false</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
<prop key="hibernate.hibernate.cache.use_query_cache">true</prop> -->
</props>
</property>
</bean>
The same goes for the used HibernateTransactionManager which also needs to be switched to hibernate4, which is simply changing the package.
For more information on Spring and hibernate integration check the reference guide.
As mentioned there is no more HibernateTemplate instead you should use the plain Hibernate API to implement repositories. More info here.
You should already have proper transactionmanagement setup but just in case check this section of the reference guide.
I have added Hibernate jars 4.0.1.Final including Hibernate Entitymanagaer, Hibernate-commons annotation, antlr 2.x,antlr-runtime2.x ..
My guess I got the problem due to not including above jars. I have added above jars my problem got resolved
com.bean.OrderDetailsVO
com.bean.OrderVO
org.hibernate.dialect.SQLServer2008Dialect
true
update</prop> -->
false</prop>
net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
true</prop> -->

Strange Behavior packageToScan and annotatedClasses when using multiple sessionFactory?

So here it goes..
I have configured two jndi in my glassfish server for communicating two different databases.And in my applicationContext.xml I have following configuration
<!-- Database connection 1 STARTS HERE-->
<jee:jndi-lookup id="JNDI1" jndi-name="jdbc/db1"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="JNDI1" />
<!-- <property name="annotatedClasses">
<list>
<value>com.test.db1.Person</value> //THIS WORKS FINE
</list>
</property>-->
<property name="packagesToScan" value="com.test.db1" /> //THIS IS STRANGE
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.autocommit">false</prop>
</props>
</property>
</bean>
<!-- Database connection 1 ENDS HERE-->
<!-- Database connection 2 STARTS HERE-->
<jee:jndi-lookup id="JNDI2" jndi-name="jdbc/db2" />
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="JNDI2" />
<property name="packagesToScan" value="com.test.db2" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.autocommit">false</prop>
</props>
</property>
</bean>
<!-- Database connection 2 ENDS HERE-->
In package com.test.db1 I have only Person class and in com.test.db2 package I have two entities named Employee and Company.
The problem occurs when I use packageToScan property in both SessionFactory beans all 3 tables are created in both databases.And when I explicitly define entity classes using annotatedClasses property tables are generated in relevant databases as configured in jndi.I am not getting why this kind of results I am getting while using packageToScan.
I'll be grateful If someone can explain me in detail.
Thank you

Nullpointer at hibernate begin transaction

I'm using hibernate with connection pooled datasource
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<property name="connectionCacheProperties">
<value>
MinLimit:10
MaxLimit:75
InitialLimit:10
ConnectionWaitTimeout:120
InactivityTimeout:180
ValidateConnection:true
MaxStatementsLimit:0
</value>
</property>
</bean>
<bean id="hibernatePropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="hibernate.properties"/>
</bean>
<!-- Database Property -->
<bean id="hibernatePropertiesPearl"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.cache.provider_class">MyCacheProvider</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.max_fetch_depth">0</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory
</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
<prop key="hibernate.transaction.auto_close_session">false</prop>
</props>
</property>
</bean>
I can see, that the connections are opened successfully in database and it's working ok, but after a while I get the following error message in logs and the server just dies:
21:48:20,700 ERROR [RentalAgreementServlet] Generic exception occurred
java.lang.NullPointerException
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
at HibernateUtil.currentSession(HibernateUtil.java:116)
The number of connections in database seems to be ok. The maximum is 75, but practically it never goes over 20.
The application deployed in JBOSS 4.2. The memory seems to be also ok when the nullpointer execption happens.
I seems to me that something is leaking, but I do not know what. Is it possible, that the connection pool think it have 75 sessions and try to increase that - at the same time the db server has just 20 connections?
I could not replicate it in development environment. I tried to kill/disconnect the sessions, break the network connections. I got different exceptions, but no nullpointerexception.
Could anyone give me a hint what to investigate what to focus on?
It looks like you are using org.hibernate.transaction.JDBCTransactionFactory in JTA environment.
Perhaps you need org.hibernate.transaction.JTATransactionFactory:
<prop key="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</prop>
The problem was that there was a part of the code where the session closing was not in the finally block. If the program throw a hibernate error, the session was left open.

Categories

Resources