Spring Roo: Two Databases Configuration

I’ve seen very often a recurrent question on Spring Roo forums. The question is “How to configure the application to handle two databases”. Certainly this is a more ample question to Spring Roo only, due it involves JPA and the Spring persistence stack. So, I believe it will be of interest to all the Spring development community that face such problem. I am assuming the Reader is a Java Developer with some familarity with Spring Roo. I focus on to how to get to configuration only. For help on how to use Roo, please visit http://www.springsource.org/roo.

Hands on the problem

I created the following minimal Roo project (shown below) for explaining the setup. I’ll modify the configuration in a way that each entity will come from different independent databases.
project --topLevelPackage org.pragmatikroo.twodb persistence setup --provider HIBERNATE --database MYSQL --userName <username> --password <password> --databaseName twodbone logging setup --level DEBUG --package PERSISTENCE entity --class ~.domain.DbOne field string --fieldName name entity --class ~.domain.DbTwo field string --fieldName name perform clean perform eclipse exit
Code language: HTML, XML (xml)

Database.properties file original

database.password=<password> database.url=jdbc\:mysql\://localhost\:3306/twodb database.username=<username> database.driverClassName=com.mysql.jdbc.Driver
Code language: HTML, XML (xml)

Database.properties file modified

database.password1=<password1> database.url1=jdbc\:mysql\://localhost\:3306/twodbone database.username1=<username1> database.password2=<password1> database.url2=jdbc\:mysql\://localhost\:3306/twodbtwo database.username2=<username2> database.driverClassName=com.mysql.jdbc.Driver
Code language: HTML, XML (xml)
Basically, I have duplicated the code from the original file delivered by Roo to define the 2nd database. This pattern would be repeated for the other files as well.

Persistence.xml file modified

<persistence-unit name="persistenceUnit1" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.josean.twodb.domain.DbOne</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/> <!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database --> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/> <property name="hibernate.connection.charSet" value="UTF-8"/> <!-- Uncomment the following two properties for JBoss only --> <!-- property name="hibernate.validator.apply_to_ddl" value="false" /--> <!-- property name="hibernate.validator.autoregister_listeners" value="false" /--> </properties> </persistence-unit> <persistence-unit name="persistenceUnit2" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.josean.twodb.domain.DbTwo</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/> <!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database --> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/> <property name="hibernate.connection.charSet" value="UTF-8"/> <!-- Uncomment the following two properties for JBoss only --> <!-- property name="hibernate.validator.apply_to_ddl" value="false" /--> <!-- property name="hibernate.validator.autoregister_listeners" value="false" /--> </properties> </persistence-unit>
Code language: HTML, XML (xml)
I duplicated the persistence unit code for the 2nd database and define unique ids. Important: Add the <class> and <exclude-unlisted-classes> as shown in the code above. As implied each entity handled by this persistence unit have to be included.

ApplicationContext.xml file modified

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource1"> <property name="driverClassName" value="${database.driverClassName}"/> <property name="url" value="${database.url1}"/> <property name="username" value="${database.username1}"/> <property name="password" value="${database.password1}"/> <property name="validationQuery" value="SELECT 1 FROM DUAL"/> <property name="testOnBorrow" value="true"/> </bean> <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory1"> <property name="dataSource" ref="dataSource1"/> <property name="persistenceUnitName" value="persistenceUnit1"/> </bean> <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager1" /> <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager1"> <property name="entityManagerFactory" ref="entityManagerFactory1" /> </bean> <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource2"> <property name="driverClassName" value="${database.driverClassName}"/> <property name="url" value="${database.url2}"/> <property name="username" value="${database.username2}"/> <property name="password" value="${database.password2}"/> <property name="validationQuery" value="SELECT 1 FROM DUAL"/> <property name="testOnBorrow" value="true"/> </bean> <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager2"> <property name="entityManagerFactory" ref="entityManagerFactory2"/> </bean> <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager2" /> <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory2"> <property name="dataSource" ref="dataSource2"/> <property name="persistenceUnitName" value="persistenceUnit2"/> </bean>
Code language: HTML, XML (xml)
Same process as the other files. Duplicate as shown. Add property attribute to the entityManagerFactory beans.

Web.xml file modified

<filter> <filter-name>Spring OpenEntityManagerInViewFilter1</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> <init-param> <param-name>entityManagerFactoryBeanName</param-name> <param-value>entityManagerFactory1</param-value> </init-param> </filter> <filter> <filter-name>Spring OpenEntityManagerInViewFilter2</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> <init-param> <param-name>entityManagerFactoryBeanName</param-name> <param-value>entityManagerFactory2</param-value> </init-param> </filter>
Code language: HTML, XML (xml)
This is it!. Application ready for deploying and testing.

Conclusion

I showed the interested Reader how to setup the application context of a Spring web app to access 2nd databases, in particular to Spring Roo Developer.

View Comments

  • Tried the two db set up and cannot get it to work using
    roo 1.1.0.RELEASE [rev 793f2b0]
    and
    sts-2.5.1.RELEASE

    I keep getting the error

    Error creating bean with name 'entityManagerFactory' defined in file [/Users/gregh/springsource.2.5.1/tc-server-developer-2.1.0.RELEASE/spring-insight-instance/wtpwebapps/crud/WEB-INF/classes/META-INF/spring/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory

    Any ideas where I can got to find out how to solve this?

  • Hi Gregg,

    Don't worry we will make to work...
    1)I want you to carefully 2ble check the configuration. It is kind-of tricky: involving many different files. One parameter wrong and It screw-up the whole thing. I don't think is the version at all. I can't remember what version I came up with it. I believe it was 1.1.1.RELEASE. Execute 1) if still the same 2)please install 1.1.1.RELEASE and give it a try.

    Please throw some lines to tell me what are you doing which such configuration. I am curious as a cat.

    We move it from there...
    B. Roogards
    jD

  • I'll upgrade roo. I basically the killer lines are related to "entityManagerFactory2". When I ad that line that is when I start getting the bean creation error on "entityManagerFactory1"

  • Weird ?

    Lets do this...
    Create a project backup (zip) file using the backup Roo bck command... Email it to me.
    Let me take a look. I'll respond asap. I am in the middle of something for the Spring Roo Forum guys right now.

    Thx
    jD

  • Gregg,

    Do this before emailing anything...
    Execute the pet clinic sample in you environment. Basically validate that Roo is working properly in first place.
    Thx
    jD

  • Okay I upgraded to roo 1.1.1.RELEASE [rev 156ccd6].

    FILE: roo.log ( I did all this inside the eclipse IDE)

    // Spring Roo 1.1.1.RELEASE [rev 156ccd6] log opened at 2011-02-24 15:12:42
    project --topLevelPackage org.octri --projectName test_release --java 6
    // Spring Roo 1.1.1.RELEASE [rev 156ccd6] log closed at 2011-02-24 15:12:44
    // Spring Roo 1.1.1.RELEASE [rev 156ccd6] log opened at 2011-02-24 15:12:45
    persistence setup --provider HIBERNATE --database MYSQL --userName XXX --password XXX --databaseName XXX
    logging setup --level DEBUG --package PERSISTENCE
    entity --class ~.domain.DbOne
    field string --fieldName name
    entity --class ~.domain.DbTwo
    field string --fieldName name
    controller all --package ~.web
    version

    FILE: database.properties

    #Updated at Thu Feb 24 15:13:18 PST 2011
    #Thu Feb 24 15:13:18 PST 2011
    database.password1=admin
    database.url1=jdbc\:mysql\://localhost\:3306/biolibrary_eval
    database.username1=root
    database.driverClassName=com.mysql.jdbc.Driver

    database.password2=admin
    database.url2=jdbc\:mysql\://localhost\:3306/biolibrary_eval2
    database.username2=root

    FILE: persistence.xml

    org.hibernate.ejb.HibernatePersistence
    org.octri.domain.DbOne



    org.hibernate.ejb.HibernatePersistence
    org.octri.domain.DbTwo
    true



    FILE: applicationContext.xml

    FILE: web.xml

    Spring OpenEntityManagerInViewFilter1
    org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

    entityManagerFactoryBeanName
    entityManagerFactory1

    Spring OpenEntityManagerInViewFilter2
    org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

    entityManagerFactoryBeanName
    entityManagerFactory2

    AND....in FILE: web.xml

    Spring OpenEntityManagerInViewFilter1
    /*

    Spring OpenEntityManagerInViewFilter2
    /*

    Resulting server startup:

    2011-02-24 15:42:05,089 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager1' defined in file [/Users/gregh/springsource.2.5.1/tc-server-developer-2.1.0.RELEASE/spring-insight-instance/wtpwebapps/test_release/WEB-INF/classes/META-INF/spring/applicationContext.xml]: Cannot resolve reference to bean 'entityManagerFactory1' while setting bean property 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory1' defined in file [/Users/gregh/springsource.2.5.1/tc-server-developer-2.1.0.RELEASE/spring-insight-instance/wtpwebapps/test_release/WEB-INF/classes/META-INF/spring/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit1] Unable to build EntityManagerFactory

  • I don't see your email around to send you the zip.

    To test things out, I first rant eh roo script and made sure it worked in single database mode. Then I started adding parts until I can to the final error.

  • Hi Jose, I don't see any of my later posts showing up on this page. so I hope not to bombard you.

    I have the pet clinic up and running, I also have a project zip I can send if you can me your email and I tried earlier to post all the config files and the error.

    You can email me at hoshovsk@ohsu.edu

  • @Gregg,

    I am glad you are up-N-running with the 2 db conf. out there...
    I won't forget what you did for my "Open Source Better Angel" mission.
    You know that to do next time you need help.

    B. Roogards
    jD

Recent Posts

  • Java

Java URL Encoder/Decoder Example

Java URL Encoder/Decoder Example - In this tutorial we will see how to URL encode/decode…

4 years ago
  • General

How to Show Multiple Examples in OpenAPI Spec

Show Multiple Examples in OpenAPI - OpenAPI (aka Swagger) Specifications has become a defecto standard…

4 years ago
  • General

How to Run Local WordPress using Docker

Local WordPress using Docker - Running a local WordPress development environment is crucial for testing…

4 years ago
  • Java

Create and Validate JWT Token in Java using JJWT

1. JWT Token Overview JSON Web Token (JWT) is an open standard defines a compact…

4 years ago
  • Spring Boot

Spring Boot GraphQL Subscription Realtime API

GraphQL Subscription provides a great way of building real-time API. In this tutorial we will…

4 years ago
  • Spring Boot

Spring Boot DynamoDB Integration Test using Testcontainers

1. Overview Spring Boot Webflux DynamoDB Integration tests - In this tutorial we will see…

4 years ago