package com.axxx.dps.apv.persistence;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
/**
* To be extended for a given entity type, and annotated by @Repository
* (access sessionFactory, instead of "session in view pattern")
*
* @author mdutoo
*
* @param <T>
*/
public abstract class GenericEntityDaoImpl<T extends GenericEntity<T>> implements GenericEntityDao<T> {
@Autowired
private SessionFactory sessionFactory;
private Class<T> objectClass;
@SuppressWarnings("unchecked")
public GenericEntityDaoImpl() {
int retriesCount = 0;
Class<?> clazz = getClass();
while(!(clazz.getGenericSuperclass() instanceof ParameterizedType) && (retriesCount < 5)) {
clazz = clazz.getSuperclass();
retriesCount ++;
}
objectClass = (Class<T>) ((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0];
}
protected final Class<T> getObjectClass() {
return objectClass;
}
protected final SessionFactory getSessionFactory() {
return sessionFactory;
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#getEntity(java.lang.Class, java.lang.Integer)
*/
@Override
public GenericEntity<?> getEntity(Class<? extends GenericEntity<?>> clazz, Integer id) {
return (GenericEntity<?>) sessionFactory.getCurrentSession().get(clazz, id);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#getById(java.lang.Number)
*/
@Override
@SuppressWarnings("unchecked")
public T getById(Number id) {
return (T) sessionFactory.getCurrentSession().get(getObjectClass(), id);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#getByField(java.lang.String, java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public T getByField(String fieldName, Object fieldValue) {
return (T) sessionFactory.getCurrentSession().createCriteria(getObjectClass()).add(Restrictions.eq(fieldName, fieldValue)).uniqueResult();
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#update(T)
*/
@Override
public void update(T entity) {
sessionFactory.getCurrentSession().update(entity);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#create(T)
*/
@Override
public void create(T entity) throws EntityNotNewException {
if (entity.isNew()) {
sessionFactory.getCurrentSession().save(entity);
} else {
throw new EntityNotNewException("Entity ID : " + entity.getId());
}
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#saveOrUpdate(T)
*/
@Override
public void saveOrUpdate(T entity) {
if (entity.isNew()) {
sessionFactory.getCurrentSession().save(entity);
} else {
sessionFactory.getCurrentSession().update(entity);
}
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#delete(T)
*/
@Override
public void delete(T entity) {
sessionFactory.getCurrentSession().delete(entity);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#refresh(T)
*/
@Override
public T refresh(T entity) {
sessionFactory.getCurrentSession().refresh(entity);
return entity;
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#list()
*/
@Override
public List<T> list() {
return list(getObjectClass(), null, null, null, null);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#listByField(java.lang.String, java.lang.Object)
*/
@Override
public List<T> listByField(String fieldName, Object fieldValue) {
Criterion filter = Restrictions.eq(fieldName, fieldValue);
return list(getObjectClass(), filter, null, null, null);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#list(java.lang.Class, org.hibernate.criterion.Criterion, org.hibernate.criterion.Order, java.lang.Integer, java.lang.Integer)
*/
@Override
@SuppressWarnings("unchecked")
public List<T> list(Class<? extends T> objectClass, Criterion filter, Order order, Integer limit, Integer offset) {
List<T> entities = new LinkedList<T>();
try {
Criteria criteria = buildCriteria(objectClass, null, filter, order, limit, offset);
entities = criteria.list();
if(order == null) {
Collections.sort(entities);
}
return entities;
} catch(DataAccessException e) {
return entities;
}
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#count()
*/
@Override
public Long count() {
return count(getObjectClass(), null, null, null, null);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#count(java.lang.Class, org.hibernate.criterion.Criterion, org.hibernate.criterion.Order, java.lang.Integer, java.lang.Integer)
*/
@Override
public Long count(Class<? extends T> objectClass, Criterion filter, Order order, Integer limit, Integer offset) {
Criteria criteria = buildCriteria(objectClass, Projections.rowCount(), filter, order, limit, offset);
Long count = (Long) criteria.uniqueResult();
return count;
}
protected Criteria buildCriteria(Class<? extends T> objectClass,
Projection projection, Criterion filter, Order order, Integer limit, Integer offset) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(objectClass);
if(projection != null) {
criteria.setProjection(projection);
}
if(filter != null) {
criteria.add(filter);
}
if(limit != null) {
criteria.setMaxResults(limit);
}
if(offset != null) {
criteria.setFirstResult(offset);
}
if(order != null) {
criteria.addOrder(order);
}
return criteria;
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#evict(T)
*/
@Override
public void evict(T object) {
sessionFactory.getCurrentSession().evict(object);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#evictCollection(java.lang.String)
*/
@Override
public void evictCollection(String roleName) {
sessionFactory.getCache().evictCollectionRegion(roleName);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#flush()
*/
@Override
public void flush() {
sessionFactory.getCurrentSession().flush();
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#setReadOnly(T, boolean)
*/
@Override
public void setReadOnly(T object, boolean readOnly) {
sessionFactory.getCurrentSession().setReadOnly(object, readOnly);
}
/* (non-Javadoc)
* @see com.axxx.dps.apv.persistence.GenericEntityDao#clearSession()
*/
@Override
public void clearSession() {
sessionFactory.getCurrentSession().clear();
}
}