For one of my projects, I have used Java 5 Generics to simplify creation of Hibernate DAO’s. I no longer have to duplicate the typical CRUD operations in every DAO class. Note that I am using HibernateDaoSupport. If you want to see an example of a non-Spring generic DAO, the authors of Hibernate have posted one on their blog. Though mine may not be the best practices for Hibernate, I thought I’d post it just to show an example of what can be done with Java 5 generics and how much code can be reduced with it.
Here is my generic class:
public abstract class AbstractHibernateDAOImpl<T extends Serializable,
KeyType extends Serializable>
extends HibernateDaoSupport {
protected Class<T> domainClass = getDomainClass();
/**
* Method to return the class of the domain object
*/
protected abstract Class<T> getDomainClass();
@SuppressWarnings("unchecked")
public T load(KeyType id) {
return (T) getHibernateTemplate().load(domainClass, id);
}
public void update(T t) {
getHibernateTemplate().update(t);
}
public void save(T t) {
getHibernateTemplate().save(t);
}
public void delete(T t) {
getHibernateTemplate().delete(t);
}
@SuppressWarnings("unchecked")
public List<T> getList() {
return (getHibernateTemplate().find("from " + domainClass.getName() + " x"));
}
public void deleteById(KeyType id) {
Object obj = load(id);
getHibernateTemplate().delete(obj);
}
public void deleteAll() {
getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
String hqlDelete = "delete " + domainClass.getName();
int deletedEntities = session.createQuery(hqlDelete).executeUpdate();
return null;
}
});
}
public int count() {
List list = getHibernateTemplate().find(
"select count(*) from " + domainClass.getName() + " x");
Integer count = (Integer) list.get(0);
return count.intValue();
}
}
I have a generic interface to go along with this class:
public interface AbstractDAO <DomainObject, KeyType> {
public DomainObject load(KeyType id);
public void update(DomainObject object);
public void save(DomainObject object);
public void delete(DomainObject object);
public void deleteById(KeyType id);
public List<DomainObject> getList();
public void deleteAll();
public int count();
}
And now for an example usage with a Hibernate domain object of type PageCache which has an Integer for its primary key. The interface:
public interface PageCacheDAO extends AbstractDAO<PageCache, Integer> {
}
And the implementation of that interface:
public class PageCacheDAOImpl extends AbstractHibernateDAOImpl<PageCache, Integer>
implements PageCacheDAO {
@Override
protected Class<PageCache> getDomainClass() {
return PageCache.class;
}
}
Note that the getDomainClass() method was just to so I could get the class name for use in my Hibernate queries. There does not appear to be a way to get it from the generic class type. Maybe there is another way to do it, or maybe I could have constructed Hibernate queries differently to work around it.
My open-sourced projects (currently inactive) that use this:
© 2017 Nilesh D Kapadia