package nu.xss.jpa.dao; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import nu.xss.jpa.entity.TypedEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class GenericJpaDao, K> implements Dao, Serializable { private static final long serialVersionUID = 4998055731089977476L; protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @PersistenceContext protected EntityManager entityManager; protected Class entity; @SuppressWarnings("unchecked") public GenericJpaDao() { ParameterizedType genericSuperclass = (ParameterizedType) getClass() .getGenericSuperclass(); this.entity = (Class) genericSuperclass.getActualTypeArguments()[0]; } public void save(E entity) { logger.info("Persist Entity: {}.", entity.toString()); entityManager.persist(entity); entityManager.flush(); logger.info("Saved entity: {}.", entity.toString()); } public void merge(E entity) { logger.info("Merge Entity: {}.", entity.toString()); entityManager.merge(entity); entityManager.flush(); logger.info("Saved entity: {}.", entity.toString()); } public void delete(E entity) { entityManager.remove(entity); logger.info("Deleted entity: {}.", entity.toString()); } public E findById(K id) { return entityManager.find(entity, id); } public List findAll() { return find(createSimpleQuery()); } protected CriteriaBuilder getCriteriaBuilder() { return entityManager.getCriteriaBuilder(); } protected CriteriaQuery createQuery() { CriteriaQuery c = getCriteriaBuilder().createQuery(this.entity); return c; } protected CriteriaQuery createSimpleQuery() { CriteriaQuery c = getCriteriaBuilder().createQuery(this.entity); Root root = c.from(this.entity); c.select(root); return c; } protected List find(CriteriaQuery query) { return entityManager.createQuery(query).getResultList(); } protected E findSingle(CriteriaQuery query) { return entityManager.createQuery(query).getSingleResult(); } protected E findSingleOrNull(CriteriaQuery query) { try { return findSingle(query); } catch (final NoResultException e) { return null; } catch (final NonUniqueResultException e) { logger.error("Found more than one result.. return first one"); return null; } } protected E findSingleFirstOrNull(CriteriaQuery query) { try { return findSingle(query); } catch (final NoResultException e) { return null; } catch (final NonUniqueResultException e) { logger.warn("Found more than one result.. return first one"); return find(query).get(0); } } }