Generic DAO design pattern with Java + Hibernate

Posted on 04-01-2013 08:37 by graham
Every application that uses Hibernate as its persistence layer should have some form of intermediate layer that abstract all the database write/read operations. Managing these operations through DAOs is the most popular design pattern to approach this issue.

DAO (Data Access Object) - is an object that performs all the data access (insert/update/retrieve/delete) operations on persistent data of some type


Data model


This tutorial assumes that you already have a model class that is properly annotated with persistence annotations or mapped using Hibernate mapping file. In our example we will use a sample class called User:
public class User
{
...
}


Generic DAO interface


The Generic DAO interface abstracts universal database operations that you will want to executed for every persistent object. These operations include:
- insert into database
- read from database
- update or save into database
- delete from database
Sample code for such interface looks as follows:
GenericDao.java
public interface GenericDao<T>
{
void delete(T obj);
T find(Integer id);
void save (T t);
List<T> findAll();
Integer countAll();
void delete(T t);
}


Generic DAO implementation


Generic DAO implementation implements functioanlity that is common to all DAOs.
GenericDaoImpl
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import javax.inject.Inject;

import org.hibernate.SessionFactory;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class GenericDaoImpl<T> extends HibernateDaoSupport implements GenericDao<T>
{
@Inject
public void initSessionFactory (SessionFactory sessionFactory)
{
setSessionFactory(sessionFactory);
}

private Class<T> type;

protected Class<T> getType()
{
return this.type;
}

protected String getClassName()
{
return type.getName();
}

@SuppressWarnings("unchecked")
public GenericDaoImpl()
{
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
type = (Class)pt.getActualTypeArguments()[0];
}

@Override
public void delete(T obj)
{
getSession().delete(obj);
}

@Override
public T find (Integer id)
{
return (T)getHibernateTemplate().get(type, id);
}

@Override
public void save (T obj)
{
getHibernateTemplate().saveOrUpdate(obj);
}

@SuppressWarnings("unchecked")
@Override
public List<T> findAll()
{
return (List<T>)getHibernateTemplate().find("FROM " + type.getName());
}

@Override
public Integer countAll()
{
return DataAccessUtils.intResult(getHibernateTemplate().find("select count(*) from " + type.getName()));
}

public void setHibernateSessionFactory(SessionFactory hibernateSessionFactory)
{
setSessionFactory(hibernateSessionFactory);
}
}

In order for this to work, a bean of type SessionFactory has to be available in the application context so that it can be injected.

Concrete DAO implementation


Now if you want to use the DAO, you have to create an subclass of GenericDAOImple for your concrete model.
@Repository
public class UserDao extends GenericDaoImpl<User>
{
// add User-specific methods here
}
Comments
send me all resources for this tuto Generic DAO design pattern with Java + Hibernate
Added on 13-05-2013 15:08 by anonymous
this function is circuitous:
@SuppressWarnings("unchecked")
public GenericDaoImpl()
{
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
type = (Class)pt.getActualTypeArguments()[0];
}

better way without reflection things and clearer code is this here:

public AbstractDBDAO(SessionFactory sessionFactory, Class<E> runtimeClass) {
this.sessionFactory = sessionFactory;

type = runtimeClass;
}

the subtype do this:

public YourSubTypeDAO extends AbstractDBDAO<your E runtime type>{

public YourSubTypeDAO() {
super(YourSubTypeDAO.class);
}
Added on 12-03-2014 11:14 by anonymous

 

Add comment

Has this tutorial been helpful to you? Or do you see anything wrong? We appreciate your opinion!
Your comment:
Show formatting hints
HTML is disallowed, but in your text you can use the following markup
  • [code][/code] for a block of code
  • [tt][/tt] for inline code
  • [link]link href|link anchor[/link] for links
  • [b][/b] for bold text
Email:
+ Ask a question
If you have a technical question related to programming and computers, ask it here. Other users will help you solve it!
Unanswered questions
Share your knowledge by helping others solve their problems