Search code examples
springspring-mvchibernate-mapping

How to map Multiple datasorce in spring-servlet.xml?


I need to connect with multiple database using hibernate in my project. I tried using 2 datasource bean tag but its not working it throws error. But if I give 1 datasource bean it works fine. Here I show my properties file and servlet.xml file.

database.properties:

#mySQL DB Properties
database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/abc
database.user=root
database.password=pass
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update


#DB2DB Properties
db2.driver=com.ibm.db2.jcc.DB2Driver
db2.url=jdbc:db2://123.141.74.323:50000/DB
db2.user=user
db2.password=pass
db2hibernate.dialect=org.hibernate.dialect.DB2Dialect
db2hibernate.show_sql=true
db2hibernate.hbm2ddl.auto=update

spring-servlet.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" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<!--Properties file  -->
<context:property-placeholder location="classpath:resources/database.properties" />

<!--Packages to scan  -->
<context:component-scan base-package="com.gcs.*" />

<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>

<tx:annotation-driven transaction-manager="hibernateTransactionManager1"/>

<!--View Resolver  -->

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass">
            <value>
                org.springframework.web.servlet.view.tiles2.TilesView
            </value>
        </property>
    </bean>
    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean>
<!--End of View Resolver  -->

<!-- mySQL DataSource -->

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.gcs.beans.SystemBean</value>
                <value>com.gcs.beans.TemplateBean</value>
                <value>com.gcs.beans.LoginBean</value>
                <value>com.gcs.beans.TestSuitBean</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>             
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

<!-- End of mySQL DataSource -->

<!-- DB2 DataSource  -->    

    <bean id="DB2dataSource" class="com.ibm.db2.jcc.DB2DataSource">  
        <property name="driverClassName" value="${db2.driver}" />
        <property name="url" value="${db2.url}" />
        <property name="username" value="${db2.user}" />
        <property name="password" value="${db2.password}" />
    </bean>

    <bean id="DB2sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="DB2dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.gcs.beans.AudTrailBean</value>
                <value>com.gcs.beans.AudTrailDtlBean</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${db2hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${db2hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${db2hibernate.hbm2ddl.auto}</prop>          
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager1"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="DB2sessionFactory" />
    </bean>

<!-- End of DB2 DataSource -->

<bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="10000000" />
</bean>

</beans>

If I comment the second datasource bean means it works fine, but I didn't comment the second datasource bean means it throws error. Below I show the error.

Error:

root cause

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gcsController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.gcs.service.LoginService com.gcs.controller.GcsController.loginService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.gcs.dao.LoginDao com.gcs.service.LoginServiceImpl.loginDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginDao': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.gcs.dao.LoginDaoImpl.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DB2sessionFactory' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: Cannot resolve reference to bean 'DB2dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DB2dataSource' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'driverClassName' of bean class [com.ibm.db2.jcc.DB2DataSource]: Bean property 'driverClassName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1055)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:562)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:871)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:423)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:443)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:459)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:340)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)

I don't know where I made mistake. I hope anyone can help me to find the error.


Solution

  • Your spring-servlet.xml looks fine. You are getting error when you are trying to inject sessionFactory. Please try the below code.

    @Transactional(value ="hibernateTransactionManager",propagation = Propagation.REQUIRED)
    public class FirstDao extends HibernateDaoSupport{
    
    
        @Autowired
        public void init(@Qualifier("sessionFactory1") SessionFactory sessionFactory) {
            setSessionFactory(sessionFactory);
        }
    
    
        public SampleEstimate fetchEstimate(long objectId){
            SampleEstimate estimate=(SampleEstimate) getSessionFactory().openSession().getNamedQuery("SampleEstimate.findOne").
                                    setLong("objectId",objectId).list().get(0);
            return estimate;
        }
    
        public void saveGroup(SampleEstimateGroup group){
            getHibernateTemplate().saveOrUpdate(group);
        }
    
    }
    

    Second Session factory injection in another Dao

        @Transactional(value = "hibernateTransactionManager1",propagation = Propagation.REQUIRED,readOnly = false)
    public class SecondDao extends HibernateDaoSupport {
    
        @Autowired
        @Qualifier("secondSessionFactory")
        public void init(SessionFactory sessionFactory){
            setSessionFactory(sessionFactory)   ;
        }
    
        public SecondDbEntity getSecondDbEntity(){
            return (SecondDbEntity)getHibernateTemplate().findByNamedQuery("SecondDbEntity.findAll").get(0);
        }
    }
    

    Hope this will help..