Friday, December 2, 2011

Multiple Database Connection in Hibernate

Multiple Database Connection in Hibernate
=========================================

Introduction

Hibernate is designed to be used with a large set of databases. The details of those databases are configured in an XML file called hibernate.cfg.xml. This configuration files could be given any name and is usually placed in the root of your application class path. There are many configuration parameters available that makes the mapping of domain model to relational model easier. The same configurations can be done from your Java class uning org.hibernate.cfg.Configuration class. If you are beginner in Hibernate, please read our article on Introduction to Hibernate ORM Framework.

Sample Application

             

The sample we discuss here shows how an Employee object can be configured to store in both Oracle Data base and Derby Database. Here we create a POJO class called Employee and store and retrieve its objects from both Oracle and Derby database.

Software Requirements

For this example I have used the following tools.
         NetBeans IDE ( may use Eclipse also)
         Hibernate 3.0
         Oracle 9i , Derby
         Sample Project Structure
         Employee.java

Employee .java
package hibernatepack.samples;
public class Employee {
        private int empid;
        private String empname;
        private double salary;

        public int getEmpid() {
                   return empid;
        }

        public void setEmpid(int empid) {
                   this.empid = empid;
        }

        public String getEmpname() {
                   return empname;
        }

        public void setEmpname(String empname) {
                   this.empname = empname;
        }

        public double getSalary() {
                   return salary;
        }

        public void setSalary(double salary) {
                   this.salary = salary;
        }
}


The mapping details of the Employee class are available in the Employee.hbm.xml file:

 Employee.hbm.xml 
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
        <hibernate-mapping>
                <class name="hibernatepack.samples.Employee" table="HBEmployeeDetails" >
                         <id name= "empid" column="EmpNo" />
                         <property name= "empname" column = "EmpName" />
                         <property name="salary" column="Salary" />
                </class>
        </hibernate-mapping>


Since we need to persist the Employee object both in Oracle and in Derby, we need to create 2 configuration files - one for Oracle, another one for Derby.


oracleconfig.cfg.xml
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
        <hibernate-configuration>
                   <session-factory>
                              <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
                              <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
                              <property name="hibernate.connection.url">
                                       jdbc:oracle:thin:@10.154.117.76:1521:oracle
                              </property>
                              <property name="hibernate.connection.username">user</property>
                              <property name="hibernate.connection.password">password</property>
                              <property name="hibernate.hbm2ddl.auto">create</property>
                              <property name="hibernate.show_sql">true</property>
                              <mapping resource="Employee.hbm.xml" />
                   </session-factory>
        </hibernate-configuration>

derbiconfig.cfg.xml
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
        <hibernate-configuration>
                    <session-factory>
                               <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
                               <property name="hibernate.connection.driver_class">
                                               org.apache.derby.jdbc.ClientDriver
                               </property>
                               <property name="hibernate.connection.url">jdbc:derby://localhost:1527/HibernateDB</property>
                               <property name="hibernate.connection.username">user</property>
                               <property name="hibernate.connection.password">pwd</property>
                               <property name="hibernate.show_sql">true</property>
                               <property name="hibernate.hbm2ddl.auto">create</property>
                               <mapping resource="Employee.hbm.xml"/>
                     </session-factory>
        </hibernate-configuration>

The IEmployeeDAO.java lists the operations on the Employee object.

IEmployeeDAO.java
package hibernatepack.samples;
import java.util.List;
public interface IEmployeeDAO {
           public void findAllEmployees();
           public void insertEmployee(Employee e);
}

Let us Implement the above interface using a class :
EmloyeeDaoImpl.java
public class EmployeeDaoImpl implements IEmployeeDAO {
           SessionFactory sessionFactory1 = new Configuration().configure("oracleconfig.cfg.xml").buildSessionFactory();
           SessionFactory sessionFactory2 = new Configuration().configure("derbyconfig.cfg.xml").buildSessionFactory();

           Session session = null;
           Transaction transaction = null;

           public void findAllEmployees() {
                      ArrayList empList = new ArrayList();
                      try {
                              session = sessionFactory1.openSession();
                              transaction = session.beginTransaction();
                              transaction.begin();
                              Criteria crit = session.createCriteria(Employee.class);
                              empList = (ArrayList) crit.list();
                              System.out.println("Records from Oracle Database");
                              for (Employee emp : empList) {
                                          System.out.println(emp.getEmpid() + " " + emp.getEmpname() + " " + emp.getSalary());
                              }
                              session.close();

                              session = sessionFactory2.openSession();
                              Criteria crit1 = session.createCriteria(Employee.class);
                              empList = (ArrayList) crit1.list();
                              System.out.println("Records from Derby Database");
                              for (Employee emp : empList) {
                                          System.out.println(emp.getEmpid() + " " + emp.getEmpname() + " " + emp.getSalary());
                              }

                              session.close();

                      } catch (Exception he) {
                                  he.printStackTrace();
                      }
           }

           public void insertEmployee(Employee e) {
                      try {
                              session = sessionFactory1.openSession();
                              transaction = session.beginTransaction();
                              transaction.begin();
                              session.save(e);
                              transaction.commit();
                              session.close();
                      
                              session = sessionFactory2.openSession();
                              transaction = session.beginTransaction();
                              transaction.begin();
                              session.save(e);
                              transaction.commit();
                              session.close();

                       } catch (HibernateException he) {
                                   he.printStackTrace();
                       }
            }
}

Creating Session Factory object in Hibernate

Each database has its own SessionFactory object.
                 SessionFactory sessionFactory1 =
                             new Configuration().configure("oracleconfig.cfg.xml").buildSessionFactory();
                 SessionFactory sessionFactory2 =
                             new Configuration().configure("derbyconfig.cfg.xml").buildSessionFactory();


Specify the name of the configuration file as an argument to the configure() method when building the session factory object. Let us create the test application.

EmployeeTest.java
package hibernatepack.samples;
import java.awt.Choice;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class EmployeeTest {
            private static int choice; public static void main(String[] args) {
                        EmployeeDaoImpl empOperations = new EmployeeDaoImpl();
                        Employee e1 = new Employee();

                        do {
                                System.out.println("1. Insert ");
                                System.out.println("2. List ");
                                System.out.println("3. Exit ");
                                System.out.println("Enter your choice ");
                                Scanner sc = new Scanner(System.in);
                               
                                choice = sc.nextInt();
                                switch (choice) {
                                            case 1:
                                                        System.out.println("Enter the employee Number ");
                                                        Scanner sc1 = new Scanner(System.in);

                                                        int empid = sc1.nextInt();
                                                        System.out.println("Enter the employee Name ");

                                                        Scanner sc2 = new Scanner(System.in);
                                                        String empname = sc2.nextLine();
                                                        System.out.println("Enter the Salary ");
                                                        Scanner sc3 = new Scanner(System.in);

                                                        double empsal = sc3.nextDouble();
                                                        e1.setEmpid(empid);
                                                        e1.setEmpname(empname);
                                                        e1.setSalary(empsal);
                                                        empOperations.insertEmployee(e1);
                                                        break;
                                            case 2:
                                                        empOperations.findAllEmployees();
                                                        break;
                                 }
                         } while (choice != 3);
             }
}


When you execute the insert method, table named “HBEMPLOYEEDETAILS” is created both in Oracle and in Derby. Find below the sample output screen.

                 

              

                


Conclusion

This is very simple example on how to configure the multiple databases using Hibernate configuration files. In the next weeks I will be writing few more examples on configuring the databases and fetching the data. In the following section you can find the interesting articles related to Hibernate framework.


Multiple Database Connection in Hibernate with Spring

figured this one out on my own. Basically, you need an applicationContext.xml for each Hibernate connection you're going to make. Here are fragments of mine applicationContext.xml

applicationContext.xml
         <beans>
                   <bean id="hibernateSession"      
                      class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
                              <property name="configLocation">   
                                          <value>file:src/hibernate.cfg.xml</value>
                              </property>
                  </bean>
                  <bean id="persistenceLayer" class="com.monitor.hibernatespring.PersistenceLayer"
                     abstract="false" singleton="true" lazy-init="default" autowire="default"
                     dependency-check="default">
                              <property name="monitorScheduleDAO">
                                          <ref bean="MonitorScheduleDAO" />
                             </property>
                 </bean>
                 <bean id="MonitorScheduleDAO"
                    class="com.monitor.hibernatespring.MonitorScheduleDAO">
                             <property name="sessionFactory">
                                          <ref bean="hibernateSession" />
                             </property>
                 </bean>
         </beans>

horseContext.xml
         <?xml version="1.0" encoding="UTF-8"?>
         <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
               "http://www.springframework.org/dtd/spring-beans.dtd">
         <beans>
                     <bean id="hibernateSession"
                            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
                                  <property name="configLocation">
                                              <value>file:src/horse.cfg.xml</value>
                                  </property>
                     </bean>
                    <bean id="horseLayer" class="com.monitor.hibernatespring.HorseLayer"
                           abstract="false" singleton="true" lazy-init="default" autowire="default"
                           dependency-check="default">
                                  <property name="chartEntryDAO">
                                              <ref bean="ChartEntryDAO" />
                                  </property>
                    </bean>
                    <bean id="ChartEntryDAO"
                           class="com.monitor.hibernatespring.ChartEntryDAO">
                                  <property name="sessionFactory">
                                              <ref bean="hibernateSession" />
                                  </property>
                    </bean>
         </beans>

hibernate.cfg.xml
         <?xml version='1.0' encoding='UTF-8'?>
         <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
               "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
         <!-- Generated by MyEclipse Hibernate Tools. -->
         <hibernate-configuration>
                    <session-factory>
                               <property name="connection.username"> netgohur_root</property>
                               <property name="connection.url">jdbc:mysql://localhost:3306/monitor_test</property>
                               <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
                               <property name="myeclipse.connection.profile">MONITOR_CHASSIS</property>
                               <property name="connection.password">mysql9tdf</property>
                               <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
                               <mapping resource="com/monitor/hibernatespring/MonitorSchedule.hbm.xml" />
                   </session-factory>
         </hibernate-configuration>

horse.cfg.xml
         <?xml version='1.0' encoding='UTF-8'?>
         <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
               "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
         <!-- Generated by MyEclipse Hibernate Tools. -->
         <hibernate-configuration>
                     <session-factory>
                                <property name="connection.username">netgohur_root</property>
                                <property name="connection.url">jdbc:mysql://localhost:3306/chart_entry</property>
                                <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
                                <property name="myeclipse.connection.profile">horse_race</property>
                                <property name="connection.password">mysql9tdf</property>
                                <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
                                <mapping resource="com/monitor/hibernatespring/MonitorSchedule.hbm.xml" />
                    </session-factory>
         </hibernate-configuration>


In my main class ...
                // Load the Spring 2 bean configuration and create a bean factory
               beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

               // Load the Spring 2 bean configuration and create a bean factory
               horseFactory = new XmlBeanFactory(new ClassPathResource("horseContext.xml"));

              // Create instance of PersistenceLayer (Spring 2)
              PersistenceLayer persistenceLayer = (PersistenceLayer) beanFactory.getBean("persistenceLayer");

             // Create instance of HorseLayer (Spring 2)
             HorseLayer horseLayer = (HorseLayer) horseFactory.getBean("horseLayer");

I guess my point is, when you right-click on
            <project> - >MyEclipse->

Add Hibernate Capability, you're only getting the possibility of connecting to a single JDBC database generated. It seems there might be some way to add the capability "Add an additional Hibernate connection."

           <?xml version="1.0"?>
           <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
                  "http://www.springframework.org/dtd/spring-beans.dtd">
           <beans>
                       <bean id="propertyConfigurer"
                                   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                                  <property name="location">
                                             <value>junit.properties</value>
                                  </property>
                      </bean>
                      <bean name="smsdDataSource" class="org.apache.commons.dbcp.BasicDataSource">
                                  <property name="driverClassName" value="${oracle.database.driver}"/>
                                  <property name="url" value="${oracle.smsd.database.url}" />
                                  <property name="username" value="${oracle.smsd.database.username}" />
                                  <property name="password" value="${oracle.smsd.database.password}" />
                      </bean>
                      <bean name="sm10DataSource" class="org.apache.commons.dbcp.BasicDataSource">
                                  <property name="driverClassName" value="${oracle.database.driver}"/>
                                  <property name="url" value="${oracle.sm10.database.url}" />
                                  <property name="username" value="${oracle.sm10.database.username}" />
                                  <property name="password" value="${oracle.sm10.database.password}" />
                      </bean>
                      <bean name="dtiDataSource"
                                  class="org.apache.commons.dbcp.BasicDataSource">
                                  <property name="driverClassName" value="${sybase.database.driver}"/>
                                  <property name="url" value="${sybase.dti.database.url}" />
                                  <property name="username" value="${sybase.dti.database.username}" />
                                  <property name="password" value="${sybase.dti.database.password}" />
                      </bean>
                      <bean id="dtiDatabaseSessionFactory"
                                  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
                                  <property name="mappingDirectoryLocations">
                                              <list>
                                                         <value>classpath:/com/sm/hibernatemaps/dti</value>
                                              </list>
                                 </property>
                                 <property name="hibernateProperties">
                                              <props>
                                                         <prop key="hibernate.dialect">${sybase.database.hibernate.dialect}</prop>
                                                         <prop key="hibernate.show_sql">${database.hibernate.showsql}</prop>
                                              </props>
                                </property>
                                <property name="dataSource" ref="dtiDataSource"/>
                      </bean>
                      <bean id="dtiTransactionManager"
                                class="org.springframework.orm.hibernate3.HibernateTransactionManager">
                                <property name="sessionFactory">
                                              <ref bean="dtiDatabaseSessionFactory" />
                                </property>
                      </bean>
                      <bean id="acctTypesManagerService" class="com.sm.dti.accttypes.AcctTypesManagerImpl">
                                <property name="sessionFactory">
                                              <ref bean="dtiDatabaseSessionFactory"/>
                                </property>
                      </bean>
           </beans>


Clieck here to download in docx format


Hibernate Articles

Interceptors in Hibernate
Integrating Spring Framework with Hibernate
Introduction to Hibernate Caching
Book Hibernate in Action



 

No comments:

Post a Comment