by October 2, 2007 0 comments



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.

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.

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
}

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:






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.

No Comments so far

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.

Your data will be safe!Your e-mail address will not be published. Also other data will not be shared with third person.