package com.jpa.dao; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.List; import org.apache.log4j.Logger; import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.Session; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Example; import com.jpa.util.HibernateUtil; /** * Default implementation. All hail ! * * @param <T> * @param <ID> * @author msaif */ public abstract class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> { private static final Logger log = Logger.getLogger(GenericHibernateDAO.class); private Class<T> persistentClass; private Session session; @SuppressWarnings("unchecked") public GenericHibernateDAO() { this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } protected Session getSession() { try { if (session == null) { log.info("getting current session [getCurrentSession()]"); session = HibernateUtil.getSessionFactory().getCurrentSession(); } } catch (HibernateException e) { log.error("No Session is associated with current Thread. " + "Make sure that you are initiating DAO instances in the TransactionScope.", e); } return session; } public void setSession(Session s) { this.session = s; } public Class<T> getPersistentClass() { return persistentClass; } @SuppressWarnings({"unchecked", "deprecation"}) 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; } 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(); } public T makePersistent(T entity) { getSession().saveOrUpdate(entity); return entity; } public void makeTransient(T entity) { getSession().delete(entity); } public void flush() { getSession().flush(); } public T save(T entity) { getSession().save(entity); return entity; } public void clear() { getSession().clear(); } /** * 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(); } /** * Get only the first object that matches the criterea * * @param criterion * @return */ protected T getFirstObjectByCriteria(Criterion... criterion) { return findByCriteria(criterion).get(0); } /** * Criteria method for pagination purpose * * @param lowerBound * @param upperBound * @param criterion * @return A list of the result within the bounds defined */ @SuppressWarnings("unchecked") protected List<T> findByCriteriaPaginated(int lowerBound, int upperBound, Criterion... criterion) { Criteria criteria = getSession().createCriteria(getPersistentClass()); criteria.setFirstResult(lowerBound); criteria.setMaxResults(upperBound); for (Criterion c : criterion) { criteria.add(c); } return criteria.list(); } }