Rajat Goyal
Rajat Goyal

Reputation: 475

multiple entityManagerFactory for 2 different datasources

I want keep 2 datasources for 2 different databases (both are mysql) like below :

<bean id="jpaVendorAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="true" />
    <property name="generateDdl" value="true" />
    <property name="database" value="MYSQL" />
</bean>

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

<bean id="entityManagerFactory-A"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource-A" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    <!-- spring based scanning for entity classes -->
    <property name="packagesToScan" value="com.package-A" />
</bean>

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

<bean id="entityManagerFactory-B"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource-B" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    <!-- spring based scanning for entity classes -->
    <property name="packagesToScan" value="com.package-B" />
</bean>

Now when i do simply this, beanInitializer gives error that entityManagerFactory is not found.

How can i have multiple entityManagerFactory, for multiple data base and what is best way to do in xml.

I googled quite a lot, but none is able to solve my problem.

It works well if i define only one entityManagerFactory, I am just stuck to have miltiple entityManagerFactory in same application context.

Upvotes: 1

Views: 1566

Answers (1)

Vijendra Kumar Kulhade
Vijendra Kumar Kulhade

Reputation: 2255

Below is the example for keeping multiple persistence unit for different type of database. Similarly 2 unit can be kept for both of your sql databases.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="oraPersistent" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>com.kulhade.us.ora.entity.BilltoAddress</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
        <validation-mode>AUTO</validation-mode>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="${db.driver}"/>
            <property name="javax.persistence.jdbc.url" value="${db.url}"/>
            <property name="javax.persistence.jdbc.user" value="${db.username}"/>
            <property name="javax.persistence.jdbc.password" value="${db.password}"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.generate_statistics" value="true"/>
            <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
            <property name="hibernate.jdbc.batch_size" value="50"/>
        </properties>
    </persistence-unit>
    <persistence-unit name="mongoPersistent" transaction-type="JTA">
        <!-- Use Hibernate OGM provider: configuration will be transparent -->
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
        <class>com.kulhade.us.mongo.entity.Sample</class>
        <class>com.kulhade.us.mongo.entity.SampleLine</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.ogm.datastore.provider" value="mongodb" />
            <property name="hibernate.ogm.datastore.database" value="${mongodb.name}"/>
            <property name="hibernate.ogm.mongodb.host" value="${mongodb.host}"/>
            <property name="hibernate.ogm.datastore.port" value="${mongodb.port}"/>
            <!--<property name="hibernate.ogm.datastore.document.association_storage" value="ASSOCIATION_DOCUMENT"/>
            <property name="hibernate.ogm.mongodb.association_document_storage" value="COLLECTION_PER_ASSOCIATION"/>-->
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
        </properties>
    </persistence-unit>
</persistence>

These multiple persistence unit can be used in Spring orm. Below is the example for it.

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="persistenceXmlLocations">
        <list>
            <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
            <value>classpath:/my/package/**/custom-persistence.xml</value>
            <value>classpath*:META-INF/persistence.xml</value>
        </list>
    </property>
    <property name="dataSources">
        <map>
            <entry key="localDataSource" value-ref="local-db"/>
            <entry key="remoteDataSource" value-ref="remote-db"/>
        </map>
    </property>
    <!-- if no datasource is specified, use this one -->
    <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitManager" ref="pum"/>
    <property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

Upvotes: 1

Related Questions