com.solace.data.jpa.GenericDao.java Source code

Java tutorial

Introduction

Here is the source code for com.solace.data.jpa.GenericDao.java

Source

/*******************************************************************************
 * Copyright (c) 2013 <a href="mailto:daniel.williams@gmail.com">Daniel Williams</a>.
 * All rights reserved. This program, solace.common.data, and file, GenericDao.java, and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     <a href="mailto:daniel.williams@gmail.com">Daniel Williams</a> - initial API and implementation
 ******************************************************************************/
package com.solace.data.jpa;

import java.util.Calendar;
import java.util.List;
import java.lang.reflect.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.solace.ExceptionHandler;
import com.solace.data.*;
import com.solace.logging.*;

/**
 * The GenericJpaDao provides the genericized functionality that you would
 * expect to find in a functional DAO implementation, abstracted. No abstract
 * factory is needed as if all implementation adhere to the concept of Entity
 * they can be injected via the Spring
 * 
 * Lazy initialization does NOT work outside of a transaction b/c no
 * EntityManager exists ergo no Session exists
 * 
 * @Repository and @Autowired annotations.
 * @author dwilliams
 * 
 * @param <ID>
 *            the identifying type of the dao
 * @param <E>
 *            the entity to per accessed
 * @see Repistory
 * @see Autowired
 */
@SuppressWarnings("unchecked")
public abstract class GenericDao<ID extends Number, E extends IEntity<ID>> implements IGenericDao<ID, E> {

    private static final String S_TOOK_D_MS_TO_EXECUTE = "{} took {} ms to execute";

    private static final String S_TOOK_D_MS_TO_EXECUTE_AND_RETURNED_D_ROWS = "{} took {} ms to execute and returned {} rows";

    private static final String MERGING_S = "merging ... {}";

    private static final String PERSISTING_S = "persisting ... {}";

    static final Logger LOGGER = Logger.getLogger(GenericDao.class);

    protected Class<E> m_persistentClass;

    protected EntityManager m_entityManager;

    public GenericDao() {
        try {
            ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
            this.m_persistentClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
        } catch (Exception e) {
        }
    }

    public EntityManager getEntityManager() {
        return this.m_entityManager;
    }

    @javax.persistence.PersistenceContext
    public void setEntityManager(EntityManager manager) {
        this.m_entityManager = manager;
    }

    @Override
    public void delete(E entity) {
        m_entityManager.remove(entity);
    }

    @Override
    public List<E> findAll() throws Exception {
        // query assumeds that the CreateDate attribute is always present
        Query q = m_entityManager
                .createQuery("SELECT e FROM " + m_persistentClass.getName() + " e order by e.createDate");
        return (List<E>) q.getResultList();

    }

    @Override
    public E findById(ID id) throws Exception {
        return m_entityManager.find(m_persistentClass, id);
    }

    @Override
    public void save(E entity) {
        if (entity.getId() == null) {
            LOGGER.debug(PERSISTING_S, entity.getClass().getName());
            m_entityManager.persist(entity);
        } else {
            LOGGER.debug(MERGING_S, entity);
            entity = m_entityManager.merge(entity);
        }
    }

    /**
     * Will take in a string query and execute it
     * 
     * @param query
     *            the query to execute
     * @return a instance of E
     * @author dwilliams
     * @note possibly create a permutation of this method which takes in a set
     *       of objects and will infer the type to be added to the query
     */
    @Override
    public E queryObject(String query, Object... args) throws Exception {

        E entity = null;

        try {
            entity = executeSingle(createQuery(query, args));
        } catch (javax.persistence.NoResultException e) {
            entity = null;
        }

        return entity;
    }

    /**
     * Will take in a string query and execute it
     * 
     * @param query                        
     *            the query to execute
     * @return a list of E
     * @author dwilliams
     * @note possibly create a permutation of this method which takes in a set
     *       of objects and will infer the type to be added to the query
     */
    @Override
    public List<E> queryObjects(String query, Object... args) throws Exception {

        List<E> entities = null;

        try {
            entities = executeList(createQuery(query, args));
        } catch (javax.persistence.NoResultException e) {
            entities = null;
        }

        return entities;
    }

    /**
     * Allows a developer to pass in a very simple DML operation
     * quickly.   
     */
    @Override
    public int executeUpdate(String query, Object... args) throws Exception {
        return createQuery(query, args).executeUpdate();
    }

    Query createQuery(String query, Object... args) throws Exception {
        Query q = m_entityManager.createQuery(query);

        if (args != null)
            for (int i = 0; i < args.length; i++)
                q.setParameter(i + 1, args[i]);

        return q;
    }

    /**
     * A simple clocking method
     * 
     * @param q
     *            the query to execute
     * @return
     */
    private List<E> executeList(javax.persistence.Query q) throws Exception {

        long now = System.currentTimeMillis();

        List<E> list = (List<E>) q.getResultList();

        LOGGER.debug(S_TOOK_D_MS_TO_EXECUTE_AND_RETURNED_D_ROWS, q.toString(), System.currentTimeMillis() - now,
                list.size());

        return list;
    }

    private E executeSingle(javax.persistence.Query q) throws Exception {

        long now = System.currentTimeMillis();

        E e = (E) q.getSingleResult();

        LOGGER.debug(S_TOOK_D_MS_TO_EXECUTE, q.toString(), System.currentTimeMillis() - now);

        return e;
    }
}