Advertisment

Integrating Hibernate with Spring

author-image
PCQ Bureau
New Update

Spring is not a rip-off from any of the existing frameworks or Open Source

projects. The reason being, it doesn't provide any ORM tool out-of-the box.

Instead, it provides integration points for ORM frameworks like Hibernate,

TopLink, iBATIS, and JPA. In this article, we'll explore how Hibernate- a

leading ORM framework; can be integrated with the Spring framework. We'll start

by looking at Spring's Data Access Objects (DAO) approach and then identify

Spring's plug-in for Hibernate ORM.

Advertisment

Spring's DAO Pattern



Spring framework is influenced by the DAO philosophy to hide the data access

code from the rest of the application and provide access through user-friendly

interface. This is a flexible design pattern which separates a data resource's

client interface from its data access mechanisms. This means the data access

code can change independently from the client code. As with other frameworks,

service objects depend on the DAO interface to access the data.

Direct Hit!
Applies To:

Adv Java Developers



USP:
Integrate Hibernate ORM with Spring and inject

dependencies through IoC container



Primary Link:





www.springframework.org/docs/reference/orm.html




Keywords:
Spring ORM

In this article, we'll develop a simple application based on our traditional

MedTracker scenario. The com.pcquest.medtracker.model package contains the model

components. This includes the POJO bean which we'll persist using Hibernate and

its corresponding mapping file. The com.pcquest. medtracker.dao package contains

the DAO interface and the implementation class. The service interface and its

corresponding implementation class is placed in the

com.pcquest.medtracker.service package. Finally, the

com.pcquest.medtracker.client package contains the stand alone application

client that will load the context definition from the Spring configuration file.

Make sure that all the required libraries are placed in the classpath.

Advertisment
The Service

object of Spring interacts with DAO at runtime

Coding the Persistence Tier



Since we're using Hibernate as an ORM solution, we'll begin by defining a

POJO bean and then use Hibernate mapping file for mapping bean properties to the

underlying table. To begin with, let's look at the POJO bean first:

package com.pcquest.medtracker.model;



public class Patient {


private int id;


private String firstName;


private String lastName;


private String sex;


private int age;


private String diagnosis;


public Patient(){


}


public Patient (int id, String firstName, String lastName, String sex, int age,
String diagnosis){



this.id=id;


this.firstName=firstName;


this.lastName=lastName;


this.sex=sex;


this.age=age;


this.diagnosis=diagnosis;


}


//getter and setters


}

















Advertisment

Patient.java is a peculiar POJO bean. It defines private properties with

public getter and setter methods, public default constructor and an overloaded

constructor. The no-argument constructor is a requirement for all persistent

classes. Note that Hibernate doesn't force you to provide getter/setter methods;

it can introspect all property types with any access automatically. Also, you

are not forced to provide public access to the constructor. However, because

Hibernate instantiates classes at runtime through reflection, at least a

constructor with default package access



is required.

Hibernate needs to know how to load and store objects of the persistent

class. This is accomplished through a mapping file which is named

Patient.hbm.xml, as shown below:



















Advertisment


Advertisment




Advertisment


Advertisment







As shown in the code listing, the mapping file tells Hibernate what table in

the database it has to access, and what columns in that table should it use. The

mapping file should be placed in the classpath. For the sake of simplicity,

we've placed the mapping file right next to the POJO bean. Also, the hbm.xml

extension is not mandatory; you are free to choose any arbitrary name. However,

it's a standard convention in the Hibernate world that all mapping files are
saved as hbm.xml.

Coding the DAO Layer



As discussed before, the DAO pattern decouples the business layer from the

persistence mechanism. The DAO abstraction layer takes the shape of an interface

as shown below:

package com.pcquest.medtracker.dao;



import com.pcquest.medtracker.model.Patient;


public interface PatientDao {


public void create(Patient patient);


public Patient get(int id);


}



Here, the PatientDao is a plain old Java interface (POJI) which acts as the

abstract factory, and the create(Patient) and get(int) methods acts as factory

methods.

Leveraging from Spring's Hibernate Template



Spring provides an out-of-box template to integrate with Hibernate called

HibernateTemplate. The HibernateTemplate acts as a wrapper around the Hibernate

core (just as Hibernate's Session is a wrapper over plain JDBC). This offloads

the developer from coding the Hibernate boilerplate- obtain a global

SessionFactory, get a Session, start a transaction and so on. However, this

approach has one drawback. By relying on HibernateTemplate you have to use the

Spring API. In addition to implementing the DAO interface, the implementation

class must extend the Spring's HibernateDaoSupport class, as shown below:

package com.pcquest.medtracker.dao;



import com.pcquest.medtracker.model.Patient;


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


public class PatientDaoImpl extends HibernateDaoSupport implements PatientDao {


public PatientDaoImpl(){}


public void create(Patient patient) {


getHibernateTemplate().save(patient);


}


public Patient get(int id){


Patient patient=(Patient) getHibernateTemplate().get(Patient.class,id);


return patient;


}


}










As shown above, the HibernateDaoSupport superclass provides a convenient

getHibernateTemplate() method. It's also worth noting that the

HibernateDaoSupport needs a SessionFactory, which we'll wire through the Spring

XML.

Coding the Service Layer



The service layer is simple, as already discussed, while the service

implementation class implements the service interface (PatientService) and HAS-A

DAO reference. We'll delegate all database access to the DAO implementation at

runtime. Later, we'll see how we'll use Spring's Inversion of Control (IoC)

container to inject a DAO implementation reference to populate the bean

reference. The service implementation class is shown here:

package com.pcquest.medtracker.service;



import com.pcquest.medtracker.dao. PatientDao;


import com.pcquest.medtracker.model. Patient;


public class PatientServiceImpl implements PatientService {


//dependency


private PatientDao patientDao;


public PatientServiceImpl(){


}


public PatientServiceImpl(PatientDao dao){


this.patientDao=dao;


}


public void addPatient(Patient patient){


this.patientDao.create(patient);


}


public Patient getPatient(int id){


return this.patientDao.get(id);


}


public PatientDao getPatientDao() {


return patientDao;


}


public void setPatientDao(PatientDao patientDao) {


this.patientDao = patientDao;


}


}





















Wiring dependencies



The only thing we are left with is wiring the dependencies through the

Spring configuration file. We need to configure a global SessionFactory. The

SessionFactory needs to know what database to connect with. This is wired

through a DataSource. The SessionFactory is then injected into the

HibernateTemplate. If you recollect from previous code snippets, we discussed

the service implementation (PatientServiceImpl) HAS-A DAO reference (PatientDao).

This means that we need to inject the DAO implementation (PatientDaoImpl) into

the service object. But, before we do that, the DAO implementation inherits a

property called HibernateTemplate from the HibernateDaoSupport superclass which

we need to inject. This is done by injecting the HibernateTemplate into the DAO

implementation. Finally, the last dependency that we need to resolve is to

inject DAO implementation in our service implementation.

The Spring configuration file which reflects the above describe dependencies

can be viewed at forums.pcquest.com under the current issue thread.

Dependency

Injection flow from Data Source to Service Implementation

Client application



The client code is simple; we'll use the ClassPathXmlApplicationContext to

load the context definition from the Sping configuration file. Make sure that

the configuration file is located in the class path. After loading the context

definition, we retrieve the patient service bean (PatientServiceImpl) by using

the getBean() method. Then in the usual manner we instantiate a new Patient

instance and call the service methods to add and retrieve the Patient record.

The following code snippet shows the taskflow:

package com.pcquest.medtracker.client;



import org.springframework.context.support.ClassPathXmlApplicationContext;


import com.pcquest.medtracker.model.*;


import com.pcquest.medtracker.service.*;


public class PatientClient {


public static final void main(String<> args) {


ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext
("Patient-context.xml");



PatientServiceImpl patientService=(PatientServiceImpl)
ctx.getBean("patientService");



patientService.addPatient(new Patient(12,"Rajat","Sharma", "Male",33, "Common
Cold"));



Patient patient=patientService.getPatient(12);


...












System.out.println("First Name:"+patient.getFirstName());



...


}

Conclusion



Spring provides out-of-box integration points for Hibernate ORM. If you

don't want any dependency on the Spring framework, you are free to use plain

Hibernate 3 API directly. Both, Hibernate and Spring offer a light weight

solution. They can be used in Java SE environments without the need to use any

Java EE app container. This is an asset over complex EJB 2.1 Entity beans where

you need to deploy your application in full blown app server. Further, since

Hibernate provides a reference implementation (RI) for the new JPA 1.0

specification, its integration with the lightweight Spring framework is getting

more popular and being adopted in production applications.


Advertisment