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

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.

Related

How to inject SchedulerFactoryBean after Spring 4.3.15 update

I am getting the following error after upgrading from Spring 4.3.2 to Spring 4.3.16:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'schedulerFactory': FactoryBean which is currently in creation returned null from getObject
I am injecting a Quartz Scheduler into one of my beans as follows:
// XML Config
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="byName">
<property name="jobFactory">
<bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory"/>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="dataSource" ref="myDS" />
<property name="triggers">
<list>
<ref bean="updateTrigger"/>
<ref bean="queueUpdateTrigger"/>
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">MyQuartzScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">60000</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.threadPool.threadCount">2</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
</props>
</property>
</bean>
<bean name="UpdateJobUtils" class="app.job.UpdateJobUtils" autowire="byType">
<property name="schedulerFactory" ref="schedulerFactory" />
</bean>
//Bean
public class UpdateJobUtils {
private StdScheduler schedulerFactory;
public void setSchedulerFactory(StdScheduler schedulerFactory) {
this.schedulerFactory = schedulerFactory;
}
...
}
This worked in Spring 4.3.2 up until 4.3.14. I see https://jira.spring.io/browse/SPR-16439 was backported to 4.3.15 so I am wondering if it changes the way I am supposed to use this class?
schedulerFactory had autowire="byName" on its configuration.
I am not sure why that was on there, but removing it seems to have fixed the exception.

Tomcat Data Source Losing Connection With DB

I need a solution about tomcat datasource configuration.
I have 2 nginx front of my tomcats.These are feeding my app, these are Webservice.
Tomcat machines and database are in different ip blog so its going firewall in each request.
When i started my tomcats everythigs well.But for example after 10 hour our after 20 hour later everythings going bad.That tomcats can not set connection.All service down.I share my datasource file and hope you find some solution or some other suggestions other than datasource file.
http://www.springframework.org/schema/beans ----
http://www.springframework.org/schema/context/spring-context.xsd">
<property name="connectionProperties">
<props merge="default">
<prop key="v$session.program">ws_${server}</prop>
</props>
</property>
<property name="connectionCacheProperties">
<props merge="default">
<prop key="MinLimit">1</prop>
<prop key="MaxLimit">120</prop>
<prop key="InitialLimit">5</prop>
<prop key="MaxStatementsLimit">50</prop>
<prop key="ConnectionWaitTimeout">30</prop>
<prop key="InactivityTimeout">600</prop>
<prop key="AbandonedConnectionTimeout">180</prop>
<prop key="PropertyCheckInterval">300</prop>
<prop key="ValidateConnection">true</prop>
<prop key="TimeToLiveTimeout">600</prop>
</props>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="nativeJdbcExtractor">
<bean class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor" />
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="com.ws.oracle.pool.JndiExporter">
<property name="bean" ref="dataSource" />
<property name="jndiName" value="dsName" />
</bean>

How define naming strategy for Hibernate bean using Spring?

I overrided all ImprovedNamingStrategy methods and placed for them breakpoints, but methods were not called in debug mode.
I have only one hibernate factory, so mistake because of other instance is impossible.
I think, the problem is in the key "hibernate.ejb.naming_strategy" or no?
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<bean id="sqlSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.${jdbc.dialect}</prop>
<prop key="hibernate.globally_quoted_identifiers=true">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">false</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">{hibernate.show_sql}</prop>
<prop key="hibernate.ejb.naming_strategy">
com.stub.utilities.dao.sql.hibernate.LowerCaseNamingStrategy
</prop>
</props>
</property>
<property name="annotatedClasses"/>
</bean>
</beans>
Pom
<spring.version>4.2.4.RELEASE</spring.version>
<hibernate.core.version>5.0.7.Final</hibernate.core.version>
Hibernate 5 doesn't have any ImprovedNamingStrategy. It uses ImplicitNamingStrategy and PhysicalNamingStrategy interfaces. Strictly speaking, there is the class ImprovedNamingStrategy, for an example, in the Hibernate 5.1. But you can't use it to configure the SessionFactory.
An example to set ImplicitNamingStrategy
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="implicitNamingStrategy">
<bean class="com.github.fluent.hibernate.cfg.strategy.hibernate5.Hibernate5NamingStrategy">
<property name="tablePrefix" value="spring_" />
</bean>
</property>
</bean>
You can use hibernate.implicit_naming_strategy and hibernate.physical_naming_strategy properties as well
<bean id="sqlSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.implicit_naming_strategy">
com.stub.utilities.dao.sql.hibernate.ImplicitNamingStrategy
</prop>
<prop key="hibernate.physical_naming_strategy">
com.stub.utilities.dao.sql.hibernate.PhysicalNamingStrategy
</prop>
</props>
</property>
<property name="annotatedClasses"/>
</bean>
</beans>
You can refer my other answer about how to implement LowerCaseNamingStrategy
Implementing a NamingStrategy in Hibernate 5 (make autogenerated column names UPPERCASE)

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

spring hibernate configuration using resource_local or jta by default?

may i know as my configuration is done directly on applicationContext.xml, i do not have persistence.xml . by default this is resource_loca or jta? do i need to add extra parameter if i want to use jta?
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<!-- xdb is defined by running the hsqldb as xdb (see above) -->
<property name="url">
<value>jdbc:oracle:thin:#theserver:1521:appsdb</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>test</value>
</property>
</bean>
<bean id="annotatedsessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="com.company.x.model" >
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</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.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.cache.provider_class">
com.company.x.services.ExternalEhCacheProvider
</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
RESOURCE_LOCAL only applies to JPA EntityManager, not to a Hibernate SessionFactory. Hibernate's Spring integration is rather smoother than it is with JPA, and so the only thing that determines the transactional behaviour is which transaction manager you use with it (either HibernateTransactionManager or JtaTransactionManager). It'll work with either one without you having to explicitly configure the SessionFactory.

Categories

Resources