Recipe: Spring + JPA Annotation + Hibernate

Modern OO applications use a lot of Models to present the business domain object. It is often that we have to write a matching data access object for each models, and in most cases they are just normal CRUD operations.

What I am trying to do here is to create a generic way to create DAO from POJO that uses JPA as mapping tool to simplify the repeating tasks. The following example uses hibernate for DB connectivity.

Of course you can simply use EJB 3.0 and remove all this completely by using method like entityManager.persist(), but if we want to stay away from EJB and persistence model, this should give you a very good place to start. (I am using JPA as my mapping tool only because of my personal preference, you can use hibernate annotation, and it should work exactly the same way).

Step 1 - Create the Generic class
I am using the sample from the "Don't repeat the DAO". I think this is pretty neat.

GenericDao Interface

package com.blogspot.programmingpanda.commons

import java.io.Serializable;
import java.util.Collection;

public interface GenericDao&ls;T, PK extends Serializable> {
Collection<T> listAll();
}


The implementation...
GenericDaoHibernateImpl

package com.blogspot.programmingpanda.commons

import java.io.Serializable;
import java.util.Collection;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class GenericDaoHibernateImpl<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T, PK> {

private Class<T> type;

public GenericDaoHibernateImpl(Class<T> type){
this.type = type;
}

public Collection<T> listAll() {
return this.getHibernateTemplate().loadAll(this.type);
}

/**
* @return the type
*/
public Class<T> getType() {
return type;
}

/**
* @param type the type to set
*/
public void setType(Class<T> type) {
this.type = type;
}
}


Once we have the generic DAO class, we can use spring to inject the model into the DAO.

Now we have to create the model and use JPA to do the O/R Mapping

Step 2 - Create the model and map it to the database

package com.blogspot.programmingpanda.commons.models;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="myschema.model")
public class MyModel implements Serializable {

private Integer id;
private String col1;
private String col2;

/**
* @return the id
*/
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}

@Column(name="col1")
public String getCol1() {
return col1;
}

@Column(name="col2")
public String getCol2() {
return col2;
}

/** And all those setter method **/



Step 3 - Spring Config
After the Model and GenericDao class, all we have to do is to
i) Let the session factory know the class(es) to map

<!-- Annotation Session Factory Bean -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="mysqlDataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<property name="annotatedClasses">
<list>

<value>com.blogspot.programmingpanda.commons.models.MyModel</value>
</list>

</property>
</bean>

ii) Create the dao by injecting the class into the GenericDao

<!-- This bean will replace the actual Dao class -->
<bean id="myModelDao" class="com.blogspot.programmingpanda.commons.GenericDaoHibernateImpl" autowire="byName">
<constructor-arg>
<value>com.blogspot.programmingpanda.commons.models.MyModel</value>
</constructor-arg>
</bean>


The full applicationContext.xml will look something like this

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/spring-config/dev.properties</value>
</list>
</property>
</bean>

<bean id="systemPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />

<!-- MySql DS -->
<bean id="mysqlDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</bean>

<!-- Annotation Session Factory Bean -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="mysqlDataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<property name="annotatedClasses">
<list>

<value>com.blogspot.programmingpanda.commons.models.MyModel</value>
</list>

</property>
</bean>
<!--sessionFactory will get autowired-->
<bean id="hibernateInterceptor"
class="org.springframework.orm.hibernate3.HibernateInterceptor"
autowire="byName" />

<!-- This bean will replace the actual Dao class -->
<bean id="myModelDao" class="com.blogspot.programmingpanda.commons.GenericDaoHibernateImpl" autowire="byName">
<constructor-arg>
<value>com.blogspot.programmingpanda.commons.models.MyModel</value>
</constructor-arg>
</bean>

<!-- Inject the Dao to an action -->
<bean id="action" class="actions.ListAction">
<property name="myModelDao" ref="myModelDao" />
</bean>

</beans>


Conclusion
This is only a minimal example demonstrating how we can use spring, JPA annotation and a generic dao template to avoid writing DAO class for each model we create in our application. You can always extend the GenericDao class to include your own method(s) other than the generic CRUD methods.

Comments (1)

Interesting Article

Spring online training Spring online training Spring Hibernate online training
Spring Hibernate online training


spring training in chennai
spring hibernate training in chennai

Post a Comment