package fi.otavanopisto.muikku.dao; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.NonUniqueResultException; import javax.persistence.Query; import fi.otavanopisto.muikku.dao.events.EntityAddEvent; import fi.otavanopisto.muikku.dao.events.EntityRemoveEvent; public abstract class AbstractDAO<T> implements Serializable { private static final long serialVersionUID = 8339666122625087683L; @Inject private Event<EntityAddEvent> entityAddEvent; @Inject private Event<EntityRemoveEvent> entityRemoveEvent; @SuppressWarnings("unchecked") public T findById(Long id) { EntityManager entityManager = getEntityManager(); return (T) entityManager.find(getGenericTypeClass(), id); } @SuppressWarnings("unchecked") public List<T> listAll() { EntityManager entityManager = getEntityManager(); Class<?> genericTypeClass = getGenericTypeClass(); Query query = entityManager.createQuery("select o from " + genericTypeClass.getName() + " o"); return query.getResultList(); } @SuppressWarnings("unchecked") public List<T> listAll(int firstResult, int maxResults) { EntityManager entityManager = getEntityManager(); Class<?> genericTypeClass = getGenericTypeClass(); Query query = entityManager.createQuery("select o from " + genericTypeClass.getName() + " o"); query.setFirstResult(firstResult); query.setMaxResults(maxResults); return query.getResultList(); } public Long count() { EntityManager entityManager = getEntityManager(); Class<?> genericTypeClass = getGenericTypeClass(); Query query = entityManager.createQuery("select count(o) from " + genericTypeClass.getName() + " o"); return (Long) query.getSingleResult(); } protected void delete(T e) { entityRemoveEvent.fire(new EntityRemoveEvent(e)); getEntityManager().remove(e); // TODO: Why is manual flush needed? flush(); } public void flush() { getEntityManager().flush(); } protected T persist(T object) { getEntityManager().persist(object); entityAddEvent.fire(new EntityAddEvent(object)); return object; } protected T getSingleResult(Query query) { @SuppressWarnings("unchecked") List<T> list = query.getResultList(); if (list.size() == 0) return null; if (list.size() == 1) return list.get(0); throw new NonUniqueResultException("SingleResult query returned " + list.size() + " elements"); } private Class<?> getFirstTypeArgument(ParameterizedType parameterizedType) { return (Class<?>) parameterizedType.getActualTypeArguments()[0]; } protected Class<?> getGenericTypeClass() { Type genericSuperclass = getClass().getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) { return getFirstTypeArgument((ParameterizedType) genericSuperclass); } else { // It's probably a weld proxy class if (genericSuperclass instanceof Class<?>) { if (AbstractDAO.class.isAssignableFrom((Class<?>) genericSuperclass)) { return getFirstTypeArgument((ParameterizedType) ((Class<?>) genericSuperclass).getGenericSuperclass()); } } } return null; } protected abstract EntityManager getEntityManager(); }