Interview Questions

Spring Hibernate Integration

In this article, lets discuss about integrating Hibernate with Spring framework.

Hibernate in short is an ORM tool which acts as a middle ware between Business layer and Database layer in an n-tier Java application.

Lets take up an example of Employee and Department tables, where each employee belongs to a department. We will see how to access those tables using Hibernate/Spring.

First of all, define the Employee and Department beans. Note that the Employee bean has a reference to Department.

Employee.java

package in.techdive.spring.hib.model;

public class Employee {

        private long empId;
        private String empName;
        private int age;
        private int salary;
        private Department dept;
               
        public Department getDept() {
                return dept;
        }
        public void setDept(Department dept) {
                this.dept = dept;
        }
        public long getEmpId() {
                return empId;
        }
        public void setEmpId(long empId) {
                this.empId = empId;
        }
        public String getEmpName() {
                return empName;
        }
        public void setEmpName(String empName) {
                this.empName = empName;
        }
        public int getAge() {
                return age;
        }
        public void setAge(int age) {
                this.age = age;
        }
        public int getSalary() {
                return salary;
        }
        public void setSalary(int salary) {
                this.salary = salary;
        }
}

Department.java

package in.techdive.spring.hib.model;

public class Department {
       
        private long deptId;
        private String deptName;
        private String branch;
       
        public long getDeptId() {
                return deptId;
        }
        public void setDeptId(long deptId) {
                this.deptId = deptId;
        }
        public String getDeptName() {
                return deptName;
        }
        public void setDeptName(String deptName) {
                this.deptName = deptName;
        }
        public String getBranch() {
                return branch;
        }
        public void setBranch(String branch) {
                this.branch = branch;
        }
}

Now create the Hibernate mapping file to map beans to tables. Here each property in the bean will be mapped to a DB column.

emp-hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
  <class name="in.techdive.spring.hib.model.Employee" table="EMPLOYEE" lazy="false">
   <id name="empId" type="long" column="EMP_ID" >
   <generator class="increment"/>
  </id>
 
  <property name="empName" unique="true">
     <column name="EMP_NAME" />
  </property>

  <property name="age">
    <column name="AGE"/>
  </property>

  <property name="salary">
    <column name="SALARY"/>
  </property>
 
   <many-to-one
        name="dept" class="in.techdive.spring.hib.model.Department"   column="DEPT_ID"/>
     
  </class>
 
   <class name="in.techdive.spring.hib.model.Department" table="DEPARTMENT">
 
   <id name="deptId" type="long" column="DEPT_ID" >
    <generator class="increment"/>
   </id>
       
   <property name="deptName">
    <column name="DEPT_NAME"/>
   </property>

   <property name="branch">
     <column name="BRANCH"/>
   </property> 
 
  </class>
 
</hibernate-mapping>

Create a Hibernate configuration file to provide the database related details.

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
      <property name="hibernate.connection.driver_class">
oracle.jdbc.driver.OracleDriver</property>
      <property name="hibernate.connection.url">
jdbc:oracle:thin:@<serverName>:<portNo>:<serviceName></property>
      <property name="hibernate.connection.username"><userName></property>
      <property name="hibernate.connection.password"><password></property>
      <property name="connection.autocommit">true</property>
      <property name="hibernate.connection.pool_size">2</property>
      <property name="show_sql">true</property>
      <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
      <property name="hibernate.hbm2ddl.auto">update</property>
      <property name="hibernate.transaction.factory_class">
          org.hibernate.transaction.JDBCTransactionFactory
        </property>
         <property name="default-lazy">true</property>
     
      <!-- Mapping files -->
     
      <mapping resource="emp-hbm.xml"/>
</session-factory>
</hibernate-configuration>

In the above hibernate.cfg.xml file, there is tag , whose resource property value should be the name of the mapping file, which we created earlier (emp-hbm.xml). We can specify more such mapping resources as per requirement.

Create the DAO's(Data Access Objects) to access the tables using Hibernate as follows.

DeptDao.java

package in.techdive.spring.hib.dao;

import in.techdive.spring.hib.model.Department;

public interface DeptDao {

        void addDepartment(Department dept);
        Department getDepartment(int deptId);
       
}

EmpDao.java

package in.techdive.spring.hib.dao;

import in.techdive.spring.hib.model.Employee;

public interface EmpDao {

        void addEmployee(Employee emp);
       
        Employee getEmployee(int empId);
}

DepartmentDaoHibImpl.java

package in.techdive.spring.hib.dao.impl;

import java.util.List;
import in.techdive.spring.hib.dao.DeptDao;
import in.techdive.spring.hib.dao.EmpDao;
import in.techdive.spring.hib.model.Department;
import in.techdive.spring.hib.model.Employee;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class DepartmentDaoHibImpl
extends HibernateDaoSupport
implements DeptDao
{

        @Override
        public void addDepartment(Department dept) {
               
                getHibernateTemplate().save(dept);
        }

        @Override
        public Department getDepartment(int deptId) {
               
                List<Department> lst = (List<Department>)getHibernateTemplate().find("from Department where deptId = "+deptId);
                return lst.get(0);
        }
}

EmpDaoHibImpl.java

package in.techdive.spring.hib.dao.impl;

import java.util.List;
import in.techdive.spring.hib.dao.EmpDao;
import in.techdive.spring.hib.model.Employee;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class EmpDaoHibImpl extends HibernateDaoSupport
implements EmpDao
{

        @Override
        public void addEmployee(Employee emp) {
               
                getHibernateTemplate().save(emp);
        }

        @Override
        public Employee getEmployee(int empId) {
               
                List<Employee> lst = (List<Employee>)getHibernateTemplate().find("from Employee where empId = "+empId);
                return lst.get(0);
        }
}

Each DAO should extend HibernateDaoSupport, a Spring helper class to support Hibernate. This class has a sessionFactory property which should be injected from spring context file. The sessionFactory bean should be specified in the spring context file, which wraps the db details.

Ok! Enough hibernate stuff. Its time to integrate it with Spring.

Create the spring application context file as follows.

hib-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd ">
<bean id="empDaoHib" class="in.techdive.spring.hib.dao.impl.EmpDaoHibImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="deptDaoHib" class="in.techdive.spring.hib.dao.impl.DepartmentDaoHibImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
</beans>

In the above spring bean configuration file, the sessionFactory bean contains a property configuration which takes the path of the hibernate.cfg.xml file so that it can load the database properties and mapping files at startup to create the schema.

Finally its time to test our code by accessing the tables.

SpringHibTest.java

package in.techdive.spring.hib;

import in.techdive.spring.hib.dao.DeptDao;
import in.techdive.spring.hib.dao.EmpDao;
import in.techdive.spring.hib.model.Department;
import in.techdive.spring.hib.model.Employee;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class SpringHibTest {

        public SpringHibTest() {
               
        }

        public static void main(String[] args) {
               
                ApplicationContext ctx =
                         new FileSystemXmlApplicationContext("src\\hib-context.xml");
               
                EmpDao empDao = (EmpDao)ctx.getBean("empDaoHib");
               
                DeptDao deptDao = (DeptDao)ctx.getBean("deptDaoHib");
               
                Department dept = new Department();
                dept.setBranch("Florida");
                dept.setDeptName("Manufacturing");
               
                deptDao.addDepartment(dept);
               
                System.out.println("dept id - "+dept.getDeptId());
               
                Employee emp = new Employee();
                emp.setEmpName("Mathews");
                emp.setAge(35);
                emp.setDept(dept);
               
                empDao.addEmployee(emp);
               
                System.out.println("employee Id - "+emp.getEmpId());
        }
}

When the above code is executed, the spring bean configuration file(hib-context.xml) loads the beans specified in the file. The sessionFactory bean will use the DB properties to create the EMPLOYEE and DEPARTMENT tables in the DB. In the above main method, we get the DeptDao to create a department record in the DB. Once the department record is created, the reference is provided to the Employee bean and it is also persisted(or stored in the DB). Have a look at the following output.

log4j:WARN No appenders could be found for logger (org.springframework.context.support.FileSystemXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.

Hibernate: select max(DEPT_ID) from DEPARTMENT
Hibernate: insert into DEPARTMENT (DEPT_NAME, BRANCH, DEPT_ID) values (?, ?, ?)
dept id - 1
Hibernate: select max(EMP_ID) from EMPLOYEE
Hibernate: insert into EMPLOYEE (EMP_NAME, AGE, SALARY, DEPT_ID, EMP_ID) values (?, ?, ?, ?, ?)
employee Id - 1

In this way Hibernate can be integrated with Spring, with the support provided by the Spring framework.

Note: Please include the necessary jar files for Spring and the following hibernate jar files,
1. hibernate3.jar
2. spring-hibernate3.jar

For Further Study
Introduction to Ibatis (ORM)