Generics sweetness

As I wrote earlier, last week I did a presentation on Hibernate as a good speaker I investigate my subject. During my investigation I came a cross the project that is being done for the Hibernate in Action second edition. In this book they used some generics for creating the CRUD DAO objects and it really opened my eyes. For me generics was a nice to have gadget for typecasting my collections, I had no idea this could be done with it. So read and be amazed!!

You have an interface like this:

public interface GenericDAO<T , ID extends Serializable>{
    T findById(ID id, boolean lock);
    List<T> findAll();
    List<T> findByExample(T exampleInstance, String... excludeProperty);
    T makePersistent(T entity);
    void makeTransient(T entity);
    void flush();
}


you have an basic implementation of this interface:

public abstract class GenericHibernateDAO<t , ID extends Serializable> implements GenericDAO<t , ID> {
    private Class<T> persistentClass;
    private Session session;
    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
     }
    @SuppressWarnings("unchecked")
    public void setSession(Session s) {
        this.session = s;
    }
    protected Session getSession() {
        if (session == null)
            throw new IllegalStateException("Session has not been set on DAO before usage");
        return session;
    }
    public Class<T> getPersistentClass() {
        return persistentClass;
    }
    @SuppressWarnings("unchecked")
    public T findById(ID id, boolean lock) {
        T entity;
        if (lock)
            entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
        else
            entity = (T) getSession().load(getPersistentClass(), id);

        return entity;
    }
    @SuppressWarnings("unchecked")
    public List<T> findAll() {
        return findByCriteria();
    }
    @SuppressWarnings("unchecked")
    public List<T> findByExample(T exampleInstance, String[] excludeProperty) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        Example example =  Example.create(exampleInstance);
        for (String exclude : excludeProperty) {
            example.excludeProperty(exclude);
        }
        crit.add(example);
        return crit.list();
    }
    @SuppressWarnings("unchecked")
    public T makePersistent(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }
    public void makeTransient(T entity) {
        getSession().delete(entity);
    }
    public void flush() {
        getSession().flush();
    }
    /**
     * Use this inside subclasses as a convenience method.
     */
    @SuppressWarnings("unchecked")
    protected List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }

}

And you have a descendent of this base class

public class BillingDetailsDAOHibernate
        extends     GenericHibernateDAO<Billingdetails , Long>
        implements  BillingDetailsDAO {

    @SuppressWarnings("unchecked")
    public List<Billingdetails> findConcrete(Class concreteClass) {
        return getSession().createCriteria(concreteClass).list();
    }
}

In short the descendent tells his parent Substitute all you T with BillingDetails and your Id with Long and abracadabra you have a simple CRUD dao for your billingDetails. Now how’s that for some fancy programming.

At the moment I’m rewritting my DAO objects to return generic collections, maybe in the next refactoring cycle I’ll use this design pattern.

My bet is that with the rise of generics, we’ll see more and more design patterns that are based on generics as this is very powerfull. The example above will surely be used in more projects to come!!

No reaction about my JUG, guess nobody is interested in learning Java. 🙁

ps sorry if wordpress f*cked up the layout, but still check it out