Generic DAO

db-chain1
For the CRUD operation in Hibernate, you don’t need to repeat Insert, Update, Delete at all. The Generic DAO can take any entity object to do this.

It can be accessed by any entity object with empty method, or some additional customize method

There are Service, and DAO layer, and your controller access Service class
Controller <-> Service <-> DAO : Source Code
model2

The interface of Generic DAO.

package com.ns.spring.dao;

import java.io.Serializable;
import java.util.List;

import com.ns.spring.exception.NSException;

public interface GenHbDao<E, K extends Serializable> {

	public List<E> findAll();	
	public E findById(K key) throws NSException;
	public void save(E obj);
	public void update(E obj);
	public void saveOrUpdate(E obj);
	public void delete(E obj);

}

The implementation of above interface

package com.ns.spring.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.ObjectNotFoundException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.ns.spring.exception.NSException;

@SuppressWarnings("unchecked")
@Repository
public abstract class GenHbDaoImpl<E, K extends Serializable> implements GenHbDao<E, K> {

	private SessionFactory sessionFactory;
	private Class<E> clazz;

	public GenHbDaoImpl() {
		Type t = getClass().getGenericSuperclass();
		ParameterizedType pt = (ParameterizedType) t;
		this.clazz = (Class<E>) pt.getActualTypeArguments()[0];
	}

	public Class<E> getCurrClazz() {
		return clazz;
	}

	@Autowired
	public void setSessionFactory(SessionFactory sf) {
		this.sessionFactory = sf;
	}

	protected Session getCurrSession() {
		return sessionFactory.getCurrentSession();
	}

	@Override
	public void save(E obj) {
		this.getCurrSession().persist(obj);
	}

	@Override
	public void update(E obj) {
		this.getCurrSession().update(obj);
	}

	@Override
	public void saveOrUpdate(E obj) {
		this.getCurrSession().saveOrUpdate(obj);
	}

	@Override
	public void delete(E obj) {
		this.getCurrSession().delete(obj);
	}

	@Override
	public List<E> findAll() {
		List<E> list = this.getCurrSession().createCriteria(getCurrClazz()).list();
		return list;
	}

	@Override
	public E findById(K key) throws NSException {
		Session session = this.getCurrSession();
		try {
			E p = (E) session.load(getCurrClazz(), key);
			return p;
		} catch (ObjectNotFoundException e) {
			throw new NSException("No result");
		}
	}
}

The interface of Service class (nearly identical of Generic DAO) that actually called by your controller.

package com.ns.spring.service;

import java.io.Serializable;
import java.util.List;

public interface GenHbService<E, K extends Serializable> {

	public List<E> findAll();
	public E findById(K key);
	public void save(E obj);
	public void update(E obj);
	public void saveOrUpdate(E obj);
	public void delete(E obj);

}

And finally the implementation of the above service interface. Notice the @Transactional annotation in each method

package com.ns.spring.service;

import java.io.Serializable;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ns.spring.dao.GenHbDao;
import com.ns.spring.exception.NSException;

@Service
public abstract class GenHbServiceImpl<E, K extends Serializable> implements GenHbService<E, K> {

	private GenHbDao<E, K> genDao;

	public GenHbServiceImpl(GenHbDao<E, K> genDao) {
		this.genDao = genDao;
	}

	public GenHbServiceImpl() {
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void save(E obj) {
		genDao.save(obj);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void update(E obj) {
		genDao.update(obj);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void saveOrUpdate(E obj) {
		genDao.saveOrUpdate(obj);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(E obj) {
		genDao.delete(obj);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public List<E> findAll() {
		return genDao.findAll();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public E findById(K key) {
		try {
			return genDao.findById(key);
		} catch (NSException e) {
			return null;
		}
	}
}