spring jpa hibernate with more datasources

hibernate, jpa, persistence-unit, spring

Solution

If you would like to use multiple `DataSource` in `Spring + JPA`.

- Create two or more `PersistenceUnit` in `persistence.xml`.

- Create `EntityManagerFactory` for each `PersistenceUnit` in `spring-beans.xml`.

More Reference.

- Multiple database with Spring+Hibernate+JPA

- Access Multiple Database Using Spring 3, Hibernate 3

- Multiple Database using Spring 3.0 and Hibernate 3.0

In your DAO classes.

@PersistenceContext(unitName ="JPA_1")
private EntityManager em_1; 

@PersistenceContext(unitName ="JPA_2")
private EntityManager em_2; 

Conig persistence.xml

<persistence-unit name="JPA_1" type="RESOURCE_LOCAL">
....
</persistence-unit>


<persistence-unit name="JPA_2" type="RESOURCE_LOCAL">
....
</persistence-unit>

Config : spring-beans.xml

<bean id="entityManagerFactory1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JPA_1"/>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/> <--if it is necessary, replace with hibernate.
    </property>
    <property name="jpaPropertyMap">
        <props>
            <prop key="eclipselink.weaving">false</prop> <--if it is necessary, replace with hibernate.
        </props>
    </property>
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver">
        </bean>
    </property>
</bean>

<bean id="entityManagerFactory2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JPA_2"/>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/> <--if it is necessary, replace with hibernate.
    </property>
    <property name="jpaPropertyMap">
        <props>
            <prop key="eclipselink.weaving">false</prop> <--if it is necessary, replace with hibernate.
        </props>
    </property>
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver">
        </bean>
    </property>
</bean> 

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> <--if it is necessary, replace with hibernate.
    <property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform"/>
    <!--<property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform" />-->
    <property name="generateDdl" value="false"/>
    <property name="showSql" value="true"/>
</bean>

Problem

I have to use two different database in my application(spring) with Hibernate,Jpa. I'd like to define the different table directly to the different data sources. So I use two different persistence unit and I try to use ``` <property name="packagesToScan" value="it.two.app.domain.first" /> ``` and ``` <property name="packagesToScan" value="it.two.app.domain.second" /> ``` putting the different tables into the different packages. but It doesn't work. Infact all the table is with the first data source. then I tried to write into the perstistence XML file the name of the class like ``` <persistence-unit name="persistenceFirst" transaction-type="RESOURCE_LOCAL"> <class>it.two.app.domain.first.OneTable</class> <exclude-unlisted-classes/> </persistence-unit> ``` and it.two.app.domain.second.OtherTable But when I run Log says Table 'firstDB.other-table' doesn't exist and I use into the services file ``` @PersistenceContext(unitName ="persistenceFirst") private EntityManager em; ``` and ``` @PersistenceContext(unitName = "persistenceSecond") EntityManager em; ``` Have you got some Ideas? Thi is the data sources XML file ``` <?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:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <!-- first datasource --> <context:property-placeholder location="classpath:jdbc-first.properties"/> <bean id="dataSourceFirst" class="org.apache.commons.dbcp.BasicDataSource" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" /> <!-- second datasource --> <context:property-placeholder location="classpath:jdbc-second.properties"/> <bean id="dataSourceSecond" class="org.apache.commons.dbcp.BasicDataSource" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" /> <bean id="transactionManagerFirst" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="emfFirst"/> <bean id="transactionManagerSecond" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="emfSecond"/> <tx:annotation-driven transaction-manager="transactionManagerFirst"/> <tx:annotation-driven transaction-manager="transactionManagerSecond"/> <jpa:repositories base-package="it.two.app.repository.first" entity-manager-factory-ref="emfFirst" transaction-manager-ref="transactionManagerFirst" /> <jpa:repositories base-package="it.two.app.repository.second" entity-manager-factory-ref="emfSecond" transaction-manager-ref="transactionManagerSecond" /> <bean id="emfFirst" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="persistenceFirst"/> <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence-first.xml"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <property name="dataSource" ref="dataSourceFirst" /> <property name="packagesToScan" value="it.two.app.domain.first" /> <property name="jpaProperties"> <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> </props> </property> </bean> <bean id="emfSecond" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="persistenceSecond"/> <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence- second.xml"/> <property name="jpaVendorAdapter" > <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> <property name="dataSource" ref="dataSourceSecond"/> <property name="packagesToScan" value="it.two.app.domain.second"/> <property name="jpaProperties"> <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> </props> </property> </bean> </beans> ``` SOLUTION!!!!!! I undestand the problem. Simply ``` <!-- first datasource --> <bean id="dataSourceFirst" class="org.apache.commons.dbcp.BasicDataSource" p:driverClassName="com.mysql.jdbc.Driver" p:url="url...." p:username="username" p:password="password" /> <!-- second datasource --> <bean id="dataSourceSecond" class="org.apache.commons.dbcp.BasicDataSource" p:driverClassName="com.mysql.jdbc.Driver" p:url="url2...." p:username="username2" p:password="password2" /> ```

Original source

Related problems