Not seeing BoneCP shutdown() with Hibernate, Spring, Bonecp - spring

I am implementing an application with Spring, Hibernate and BoneCP. When I invoke the shutdown script of Tomcat I see errors like this
The web application [/REST] appears to have started a thread named [BoneCP-release-thread-helper-thread] but has failed to stop it. This is very likely to create a memory leak.
When i see my logs, I am not seeing "Shutting down connection pool...", so I am assuming I am missing something over here.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-1.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
xmlns:context="http://www.springframework.org/schema/context">
<bean id="LookupService" class="com.appserver.rest.LookupService">
<property name="userManager" ref="UserManager"></property>
<property name="groupManager" ref="GroupManager"></property>
<property name="messageManager" ref="MessageManager"></property>
<property name="tokenManager" ref="TokenManager"></property>
<property name="accessManager" ref="AccessManager"></property>
<property name="rosterManager" ref="RosterManager"></property>
</bean>
<bean id="LookupServiceV2" class="com.appserver.rest.LookupServiceV2"
parent="LookupService">
</bean>
<bean id="UserManager" class="com.appserver.rest.UserManager">
<constructor-arg index="0">
<ref bean="authManager" />
</constructor-arg>
</bean>
<bean id="GroupManager" class="com.appserver.rest.GroupManager">
<constructor-arg index="0">
<ref bean="authManager" />
</constructor-arg>
</bean>
<bean id="MessageManager" class="com.appserver.rest.MessageManager">
</bean>
<bean id="TokenManager" class="com.appserver.rest.TokenManager">
<constructor-arg index="0">
<ref bean="secureRandom" />
</constructor-arg>
</bean>
<bean id="authManager" class="com.appserver.rest.AuthenticationManager">
<constructor-arg index="0">
<ref bean="secureRandom" />
</constructor-arg>
</bean>
<bean id="AccessManager" class="com.appserver.rest.AccessManager">
</bean>
<bean id="RosterManager" class="com.appserver.rest.RosterManager">
</bean>
<bean id="secureRandom" class="java.security.SecureRandom">
</bean>
<bean id="messageDeleteScheduler" class="com.appserver.schema.MessageDeleteScheduler" />
<bean id="messageDeleteJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="messageDeleteScheduler" />
<property name="targetMethod" value="scheduleMessageDeletion" />
</bean>
<bean id="messageDeleteTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="messageDeleteJob" />
<property name="repeatInterval" value="3600000" />
<property name="startDelay" value="1000" />
</bean>
<bean id="quartz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" destroy-method="destroy" >
<property name="jobDetails">
<list>
<ref bean="messageDeleteJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="messageDeleteTrigger" />
</list>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
autowire="autodetect">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.appserver.schema.GroupDB</value>
<value>com.appserver.schema.UserDB</value>
<value>com.appserver.schema.MessageDB</value>
<value>com.appserver.schema.UserBlockDB</value>
<value>com.appserver.schema.GroupUserMapperDB</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!-- <prop key="hibernate.connection.provider_class">com.jolbox.bonecp.provider.BoneCPConnectionProvider</prop> -->
<!-- <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost/testdb</prop>
<prop key="hibernate.connection.username">alpha1</prop>
<prop key="hibernate.connection.password">r0cktheworld</prop>
<prop key="hibernate.connection.pool_size">50</prop>
-->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.globally_quoted_identifiers">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EHCacheProvider</prop>
<!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> -->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<!-- this is connection provider -->
<!-- and this is how you configure it -->
<prop key="jadira.usertype.autoRegisterUserTypes">true</prop>
<prop key="jadira.usertype.databaseZone">jvm</prop>
<prop key="jadira.usertype.javaZone">jvm</prop>
</props>
</property>
</bean>
<!-- Spring bean configuration. Tell Spring to bounce off BoneCP -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref local="mainDataSource" />
</property>
</bean>
<bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost/dbrocker" />
<property name="username" value="root"/>
<property name="password" value="root123"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="60"/>
<property name="minConnectionsPerPartition" value="20"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="10"/>
<property name="statementsCacheSize" value="50"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
<context:annotation-config/>
Thanks

This is a known issue. See https://code.google.com/p/guava-libraries/issues/detail?id=92.
Try using the snapshot version of bonecp-0.8.0-rc2 which contains 14.0.1 version of guava that has fixes for guava Finalizer thread not closed.
You can grab the snapshot from here -> https://oss.sonatype.org/content/repositories/snapshots/com/jolbox/bonecp/0.8.0-rc2-SNAPSHOT/

Related

FATAL: database "dbName/" does not exist

I am using Spring 4.3.9, Hibernate 5.4.1 with PostgresQL 9.3.
When I start tomcat container using ./catalina.sh run. I get below error in the log file.
org.postgresql.util.PSQLException: FATAL: database "emgda/" does not exist
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440)
at org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2559)
at org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:133)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:250)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
at org.postgresql.Driver.makeConnection(Driver.java:454)
at org.postgresql.Driver.connect(Driver.java:256)
at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Though the database along with data exists. Below are the configurations.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.postgresql.Driver"/>
<property name="jdbcUrl" value="jdbc:postgresql://192.168.1.230:5432/emgda/"/>
<property name="user" value="user"/>
<property name="password" value="some_password"/>
<property name="minPoolSize" value="20"/>
<property name="maxPoolSize" value="50"/>
<property name="breakAfterAcquireFailure" value="false"/>
<property name="acquireRetryAttempts" value="3"/>
<property name="idleConnectionTestPeriod" value="300"/>
<property name="testConnectionOnCheckout" value="true"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.emg.server.db.Apps</value>
</list>
</property>
</bean>
<bean id="emgDaoSupport" class="com.emg.server.db.EMGDaoSupport">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
Remove last "/" on jdbc:postgresql://192.168.1.230:5432/emgda/,

Atomikos, Hibernate 4/5, Spring 4, Jetty - unable to locate current JTA transaction

I have tried many different solutions, but getting the exception:
org.hibernate.HibernateException: Unable to locate current JTA transaction
I am using Atomikos, Hibernate 4/5, Spring 4 and Jetty.
How to configure Spring 4 + Hibernate 4/5 (non JPA)?
Atomikos documentation only has an example with JPA.
I would be very grateful for a working example (non JPA, non JEE Application server).
This example changes non JPA:
<context:annotation-config />
<context:component-scan base-package="com.atomikos.icatch.jta.hibernate4" />
<tx:annotation-driven transaction-manager="transactionManager" mode="proxy" proxy-target-class="false" />
<aop:aspectj-autoproxy />
<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="dataSource">
<property name="forceShutdown" value="true" />
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<!-- by default : looks for java:comp/UserTransaction -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="atomikosUserTransaction"></property>
<property name="transactionManager" ref="atomikosTransactionManager"></property>
</bean>
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
destroy-method="close" init-method="init" >
<property name="uniqueResourceName" value="atomikos-standalone" />
<property name="maxPoolSize" value="10" />
<property name="minPoolSize" value="5" />
<property name="testQuery" value="SELECT 1" />
<property name="xaDataSource" ref="xaReferent" />
</bean>
<bean id="xaReferent" class="org.h2.jdbcx.JdbcDataSource">
<property name="URL" value="jdbc:h2:~/test-db;MODE=PostgreSQL;MVCC=TRUE;DB_CLOSE_DELAY=-1" />
<property name="user" value="sa" />
<property name="password" value="" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.atomikos.icatch.jta.hibernate4"/>
<property name="jtaTransactionManager" ref="transactionManager" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.transaction.jta.platform">com.atomikos.icatch.jta.hibernate4.AtomikosPlatform</prop>
<prop key="show_sql" >true</prop>
</props>
</property>
</bean>
</beans>
Update
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.atomikos.icatch.jta.hibernate4"/>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.jta.platform">com.atomikos.icatch.jta.hibernate4.AtomikosPlatform</prop>
<prop key="hbm2ddl.auto">create</prop>
<prop key="connection.release_mode">auto</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>

Configure Spring JMS with JTA and Atomikos

I want to achieve the following:
i) we have a weblogic queue and external applications would be writing into the queue
ii)I have to write a stand-alone application which can read and write into this queue inside a transaction. i.e. the messages from the queue has to be persisted into DB. So in case of any error at any stage, the transaction should rollback and the message should be available in the queue again.
To achieve this I have done some self study and came across the below URL:
http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html?page=3
I have understood that I have to use JTA and XA resources for this. I have tried using Atomikos as the JTA Transaction manager following the below URL:
http://www.atomikos.com/Documentation/SpringIntegration
After trying whole day I have comeup with the following incomplete applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">t3://somehost.corp.com:8011</prop>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
</props>
</property>
</bean>
<!--
This is an interface not a concreate class. Not sure what needs to go here for weblogic queue connection factory.
<bean id="xaFactory" class="javax.jms.XAConnectionFactory">
<property name="brokerURL" value="t3://somehost.corp.com:8011" />
</bean> -->
<bean id="ConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="jms/AuditCF" />
<property name="xaConnectionFactory" ref="xaFactory" />
</bean>
<bean id="JtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="myDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jms/AuditQ</value>
</property>
</bean>
<bean id="service" class="com.samples.AccountService">
<property name="jmsTemplate">
<ref bean="jmsTemplate" />
</property>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="ConnectionFactory" />
</property>
<property name="defaultDestination">
<ref bean="myDestination" />
</property>
<property name="destinationResolver" ref="jndiResolver" />
</bean>
<!-- a class that implements javax.jms.MessageListener -->
<bean id="MessageListener" class="com.samples.Messages" />
<bean id="MessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="transactionManager" ref="JtaTransactionManager" />
<property name="connectionFactory" ref="ConnectionFactory" />
<property name="messageListener" ref="MessageListener" />
<property name="destinationName" value="jms/AuditQ" />
<property name="concurrentConsumers" value="1" />
<property name="receiveTimeout" value="3000" />
<property name="sessionTransacted" value="true" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>weblogic.jms.XAConnectionFactory</value>
</property>
</bean>
<bean id="jndiResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
<!-- <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="receiveTimeout">
<value>0</value>
</property>
<property name="destinationResolver" ref="jndiResolver" />
</bean> -->
<bean id="datasource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<!-- set an arbitrary but unique name for the datasource -->
<property name="uniqueResourceName">
<value>XADBMS</value>
</property>
<!-- set the underlying driver class to use, in this example case we use
Oracle -->
<property name="xaDataSourceClassName">
<value>oracle.jdbc.xa.client.OracleXADataSource</value>
</property>
<property name="xaProperties">
<props>
<prop key="user"><user></prop>
<prop key="password"><pwd></prop>
<prop key="URL">jdbc:oracle:thin:#host:3028/DB
</prop>
</props>
</property>
<!-- how many connections in the pool? -->
<property name="poolSize" value="3" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan" value="com.samples">
</property>
<property name="dataSource">
<ref bean="datasource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.connection.isolation">3</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</prop>
<prop key="hibernate.transaction.manager_lookup_class">
com.atomikos.icatch.jta.hibernate4.TransactionManagerLookup
</prop>
</props>
</property>
</bean>
</beans>
As shown in the Spring-Atomikos integration example, the XAConnectionFactory has been mentioned as :
<bean id="xaFactory"
class="org.apache.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
I am unable to find the related configuration I need to do for weblogic queue. I have tried using "weblogic.jms.XAConnectionFactory" as the class, but I get classnotfoundexception for that.
I dont have any experience working with JTA or XA. Kindly guide me.

Spring same dataSource for different JdbcTemplates

I have different DAO's that have the same class that require different jdbcTemplates who all use the same type of dataSources. Is there a way to consolidate my code, so I don't need to use so much copy and paste.
An example of what I have in xml is:
<bean id="jdbcTemplate1" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jdbcDataSource1" />
</bean>
<bean id="jdbcDataSource1" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSource.url">dataSourceUrl
</prop>
<prop key="dataSource.user">user</prop>
<prop key="dataSource.password">password</prop>
</props>
</constructor-arg>
<property name="dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
</bean>
</constructor-arg>
</bean>
<bean id="jdbcTemplate2" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jdbcDataSource2" />
</bean>
<bean id="jdbcDataSource2" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSource.url">dataSourceUrl
</prop>
<prop key="dataSource.user">user</prop>
<prop key="dataSource.password">password</prop>
</props>
</constructor-arg>
<property name="dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
</bean>
</constructor-arg>
</bean>
As seen by the code, jdbcDataSource1 and jdbcDataSource2 are the same. So is there a way to consolidate the two?
This would be the way to pass the same datasource to the two JDBC templates:
<bean id="jdbcTemplate1" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jdbcDataSource" />
</bean>
<bean id="jdbcTemplate2" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jdbcDataSource" />
</bean>
<bean id="jdbcDataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSource.url">dataSourceUrl
</prop>
<prop key="dataSource.user">user</prop>
<prop key="dataSource.password">password</prop>
</props>
</constructor-arg>
<property name="dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
</bean>
</constructor-arg>
</bean>
You can keep one template and one datasource in bean definitions. If your dao's template are already predefined and you don't want to change it, you can still use only one jdbc template as follows:
<bean id="yourDao1" class="package.YourDao1">
<property name="jdbcTemplate1" ref="jdbcTemplate" />
</bean>
<bean id="yourDao2" class="package.YourDao2">
<property name="jdbcTemplate2" ref="jdbcTemplate" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jdbcDataSource" />
</bean>
<bean id="jdbcDataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSource.url">dataSourceUrl
</prop>
<prop key="dataSource.user">user</prop>
<prop key="dataSource.password">password</prop>
</props>
</constructor-arg>
<property name="dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
</bean>
</constructor-arg>
</bean>

spring how to write config to support 2 database

i try to config a data source ----> mysql
the other data source ----> h2 in memory (embedded )
with the following config:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost/item"
p:username="" p:password="" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop>
</props>
</property>
<property name="packagesToScan" value="*************" />
</bean>
<!-- Spring transaction management -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="org.h2.tools.Server" class="org.h2.tools.Server" scope="singleton" factory-method="createTcpServer"
init-method="start" depends-on="org.h2.tools.Server-WebServer">
<constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,9092"/>
</bean>
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server" scope="singleton" factory-method="createWebServer" init-method="start">
<constructor-arg value="-web,-webAllowOthers,true,-webPort,8082"/>
</bean>
<!-- notice that loading the Driver as a bean is unnecessary is most cases! u could safely remove this and the depends-on in the next bean -->
<bean id="H2DatabaseJDBCDriver" class="org.h2.Driver" scope="singleton" init-method="load" depends-on="org.h2.tools.Server"/>
<bean id="H2InMemoryDB"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
depends-on="org.h2.tools.Server">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:appdb1;DB_CLOSE_DELAY=-1" />
<!-- ;TRACE_LEVEL_FILE=3;TRACE_LEVEL_SYSTEM_OUT=3 -->
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="H2InMemoryDBPool" class="org.apache.commons.pool.impl.GenericObjectPool">
<!-- Two connections: InMemoryEntityManagerFactory and transactionManager -->
<property name="minIdle" value="1"/>
<property name="maxWait" value="10"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="10"/>
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
</bean>
<bean id="H2InMemoryDBDSConnFactory" class="org.apache.commons.dbcp.DataSourceConnectionFactory">
<constructor-arg><ref bean="H2InMemoryDB"/></constructor-arg>
</bean>
<bean id="H2InMemoryDBPoolableConnFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory">
<constructor-arg index="0"><ref bean="H2InMemoryDBDSConnFactory"/></constructor-arg>
<constructor-arg index="1"><ref bean="H2InMemoryDBPool"/></constructor-arg>
<constructor-arg index="2"><null/></constructor-arg>
<constructor-arg index="3"><null/></constructor-arg>
<constructor-arg index="4"><value>false</value></constructor-arg>
<constructor-arg index="5"><value>true</value></constructor-arg>
</bean>
<bean id="pooledInMemoryDB" class="org.apache.commons.dbcp.PoolingDataSource" depends-on="H2InMemoryDBPoolableConnFactory">
<constructor-arg><ref bean="H2InMemoryDBPool"/></constructor-arg>
</bean>
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="pooledInMemoryDB">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
<property name="packagesToScan" value="********" />
</bean>
<bean id="transactionManager2"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
but its not work .
so my question is :
do i need to use 2 session factory or using dynamic data source switch ?
Thanks
I did find a typo that may cause you code to break.
Your second transactionmanager refers to the first sessionFactory. I think you want it to refer to the second transactionmanager. Try:
<bean id="transactionManager2"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory2" />
Regarding your question whether one has to use some sort of "dynamic data source switch" as described here, multiple data sources should just be fine.
i use
<jdbc:embedded-database id="embeddedDatasource" type="DERBY">
<jdbc:script location="classpath:test.sql"/>
</jdbc:embedded-database>
instead
it works

Resources