package de.dhbw.humbuch.model; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.persistence.EntityManager; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Order; import com.google.common.eventbus.EventBus; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.TypeLiteral; import com.google.inject.persist.Transactional; import de.dhbw.humbuch.event.EntityUpdateEvent; import de.dhbw.humbuch.model.entity.Entity; /** * Generic {@link DAO} implementation * * @author davherrmann * @param <EntityType> */ public class DAOImpl<EntityType extends Entity> implements DAO<EntityType> { private Provider<EntityManager> emProvider; private EventBus eventBus; private Class<EntityType> entityClass; @SuppressWarnings("unchecked") @Inject public DAOImpl(TypeLiteral<EntityType> entityType, Provider<EntityManager> emProvider, EventBus eventBus) { this.emProvider = emProvider; this.eventBus = eventBus; entityClass = (Class<EntityType>) entityType.getRawType(); } @Override @Transactional public EntityType insert(EntityType entity) { return insert(entity, FireUpdateEvent.NO); } @Override @Transactional public EntityType insert(EntityType entity, FireUpdateEvent fireUpdateEvent) { getEntityManager().clear(); EntityType mergedEntity = getEntityManager().merge(entity); if(fireUpdateEvent == FireUpdateEvent.YES) { fireUpdateEvent(); } return mergedEntity; } @Override @Transactional public Collection<EntityType> insert(Collection<EntityType> entities) { return insert(entities, FireUpdateEvent.NO); } @Override @Transactional public Collection<EntityType> insert(Collection<EntityType> entities, FireUpdateEvent fireUpdateEvent) { getEntityManager().clear(); Collection<EntityType> mergedEntities = new ArrayList<>(); for (EntityType entity : entities) { mergedEntities.add(getEntityManager().merge(entity)); } if(fireUpdateEvent == FireUpdateEvent.YES) { fireUpdateEvent(); } return mergedEntities; } @Override public EntityType find(final Object id) { getEntityManager().clear(); return (EntityType) getEntityManager().find(getEntityClass(), id); } @SuppressWarnings("unchecked") @Override public List<EntityType> findAllWithCriteria( final Criterion... criteriaArray) { getEntityManager().clear(); Session session = (Session) getEntityManager().getDelegate(); Criteria criteria = session.createCriteria(getEntityClass()); for (Criterion criterion : criteriaArray) { criteria.add(criterion); } return criteria.list(); } @SuppressWarnings("unchecked") @Override public List<EntityType> findAllWithCriteria(Order order, Criterion... criteriaArray) { getEntityManager().clear(); Session session = (Session) getEntityManager().getDelegate(); Criteria criteria = session.createCriteria(getEntityClass()); criteria.addOrder(order); for(Criterion criterion : criteriaArray) { criteria.add(criterion); } return criteria.list(); } @Override public List<EntityType> findAll() { getEntityManager().clear(); return getEntityManager().createQuery( "from " + getEntityClass().getSimpleName(), getEntityClass()) .getResultList(); } @Override public EntityType findSingleWithCriteria(Criterion... criteriaArray) { getEntityManager().clear(); List<EntityType> resultList = findAllWithCriteria(criteriaArray); if (resultList.size() > 0) { return resultList.get(0); } else { return null; } } @Override public EntityType findSingleWithCriteria(Order order, Criterion... criteriaArray) { getEntityManager().clear(); List<EntityType> resultList = findAllWithCriteria(order, criteriaArray); if(resultList.size() > 0) { return resultList.get(0); } else { return null; } } @Override @Transactional public void update(EntityType entity) { update(entity, FireUpdateEvent.NO); } @Override @Transactional public void update(EntityType entity, FireUpdateEvent fireUpdateEvent) { getEntityManager().clear(); getEntityManager().merge(entity); if(fireUpdateEvent == FireUpdateEvent.YES) { fireUpdateEvent(); } } @Override @Transactional public void update(Collection<EntityType> entities) { update(entities, FireUpdateEvent.NO); } @Override @Transactional public void update(Collection<EntityType> entities, FireUpdateEvent fireUpdateEvent) { getEntityManager().clear(); for (EntityType entity : entities) { getEntityManager().merge(entity); } if(fireUpdateEvent == FireUpdateEvent.YES) { fireUpdateEvent(); } } @Override @Transactional public void delete(EntityType entity) { delete(entity, FireUpdateEvent.NO); } @Override @Transactional public void delete(EntityType entity, FireUpdateEvent fireUpdateEvent) { getEntityManager().clear(); getEntityManager().remove(getEntityManager().merge(entity)); if(fireUpdateEvent == FireUpdateEvent.YES) { fireUpdateEvent(); } } @Override @Transactional public void delete(Collection<EntityType> entities) { delete(entities, FireUpdateEvent.NO); } @Override @Transactional public void delete(Collection<EntityType> entities, FireUpdateEvent fireUpdateEvent) { getEntityManager().clear(); for (EntityType entity : entities) { getEntityManager().remove(getEntityManager().merge(entity)); } if(fireUpdateEvent == FireUpdateEvent.YES) { fireUpdateEvent(); } } @Override public EntityManager getEntityManager() { return emProvider.get(); } @Override public Class<EntityType> getEntityClass() { return entityClass; } @Override public void fireUpdateEvent() { eventBus.post(new EntityUpdateEvent(getEntityClass())); } }