com.autentia.intra.dao.hibernate.HibernateManagerBase.java Source code

Java tutorial

Introduction

Here is the source code for com.autentia.intra.dao.hibernate.HibernateManagerBase.java

Source

/* 
 *  TNTConcept Easy Enterprise Management by Autentia Real Bussiness Solution S.L.  
 *   Copyright (C) 2007 Autentia Real Bussiness Solution S.L.                  
 *   
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation; either version 2
 *    of the License, or (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 *    Autentia Real Bussiness Solution S.L.
 *    Tlf: +34 91 675 33 06, +34 655 99 11 72
 *    Fax: +34 91 656 65 04
 *    info@autentia.com                                                
 */

/*
 * HibernateManagerBase.java
 */
package com.autentia.intra.dao.hibernate;

import com.autentia.intra.businessobject.Historial;
import com.autentia.intra.businessobject.HistorialType;
import com.autentia.intra.dao.DataAccException;
import com.autentia.intra.dao.ITransferObject;
import com.autentia.intra.dao.SearchCriteria;
import com.autentia.intra.dao.SortCriteria;
import com.autentia.intra.util.HibernateUtil;
import com.autentia.intra.util.SpringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.Query;
import org.hibernate.Session;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;

/**
 * Clase abstracta base de todas las clases que resuelven la lgica de negocio de la aplicacin
 * Hace trabajo comn a la hora de acceder a base de datos mediante hibernate
 *
 * @author <a href="www.autentia.com">AUTENTIA</a>
 */

public abstract class HibernateManagerBase /*implements IManager*/ {

    /**
     * El objeto logger
     */
    private static final Log log = LogFactory.getLog(HibernateManagerBase.class);

    /**
     * Get all existing objects of an entity
     *
     * @param <T>   type of entity the manager works with
     * @param clazz entity class
     * @param crit  sort criteria (can be null)
     * @return the list of all existing object ordered by criteria
     * @throws DataAccException
     */
    protected <T extends Object> List<T> list(Class<T> clazz, SortCriteria crit) throws DataAccException {
        return (List<T>) getAll(clazz.getName(), crit);
    }

    /**
     * Get DAOs matching searching criteria
     *
     * @param <T>    type of entity the manager works with
     * @param clazz  entity class
     * @param search search criteria
     * @param sort   sort criteria (can be null)
     * @return the list of objects matching the criteria
     * @throws DataAccException
     */
    protected <T extends Object> List<T> search(Class<T> clazz, SearchCriteria search, SortCriteria sort)
            throws DataAccException {
        log.debug("search - clazz='" + clazz + "' search='" + search + "' sort='" + sort + "'");

        List<T> ret = null;

        try {
            // Append FROM condition
            StringBuilder query = new StringBuilder("FROM ");
            query.append(clazz.getName());

            query.append(" p");

            // Append WHERE condition
            if (search != null) {
                query.append(" ");
                query.append(search.getHQL());
            }

            // Append ORDER BY condition
            if (sort != null) {
                query.append(" ");
                query.append(sort.getHQL());
            }

            // Make query
            ret = (List<T>) search(query.toString(), (search == null) ? new Object[0] : search.getArguments());

            log.debug("search - found " + ret.size() + " objects of type " + clazz.getName());
        } catch (Exception ex) {
            log.error("search - error searching", ex);
            throw new DataAccException("Error searching " + clazz.getName() + " objects", ex);
        }

        return ret;
    }

    /**
     * Perform a custom Hibernate HQL search.
     *
     * @param hql the hql query
     * @return a List of Objects with the result
     * @throws DataAccException
     * @oaram args query parameters
     */
    @SuppressWarnings("unchecked")
    protected List search(String hql, Object... args) throws DataAccException {
        log.debug("search - hql='" + hql + "'");

        Session session = null;
        List<Object> ret = null;

        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            Query q = session.createQuery(hql);
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof Collection) {
                    q.setParameterList("arg" + i, (Collection) args[i]);
                } else {
                    q.setParameter("arg" + i, args[i]);
                }
            }
            ret = q.list();
            session.getTransaction().commit();

            log.debug("search - found " + ret.size() + " objects");
        } catch (Exception ex) {
            log.error("search - error searching", ex);
            throw new DataAccException("Error searching '" + hql + "'", ex);
        }

        return ret;
    }

    /* Sin revisar **********************************************************************************************/

    /**
     * El objeto logger para el cach
     */
    private static Log loggerCache = LogFactory.getLog(HibernateManagerBase.class);

    /**
     * Cach de objetos de base de datos
     */
    private static Hashtable cache = new Hashtable();

    /**
     * Indicador de si las operaciones que se van a efectuar en esta instancia van a interactuar con el cach
     */
    protected boolean cacheable = false;

    /**
     * Crea una nueva instancia de esta clase
     */
    protected HibernateManagerBase() {
    }

    /**
     * Crea una nueva instancia de esta clase
     *
     * @param cacheable indica si las operaciones en esta instancia deben tener en
     *                  cuenta la cach
     */
    protected HibernateManagerBase(boolean cacheable) {
        this.cacheable = cacheable;
    }

    public void setCacheable(boolean cacheable) {
        this.cacheable = cacheable;
    }

    public boolean isCacheable() {
        return cacheable;
    }

    /**
     * Devuelve un objeto de negocio por clave primaria.
     *
     * @param pk Una instancia de la clave primaria
     * @return Una instancia del objeto recuperado de base de datos o null en el caso de no
     *         encontrar ningn objeto con la clave primaria especificada
     */
    protected <T extends Object> T getByPk(Class<T> theClass, Serializable pk) throws DataAccException {
        T objResult = null;
        Session session = HibernateUtil.currentSession();
        objResult = getByPk(theClass, pk, session);
        return objResult;
    }

    /**
     * Devuelve un objeto de negocio por clave primaria.
     *
     * @param theClass Instancia vaca del objeto que se desea recuperar
     * @param pk       Una instancia de la clave primaria
     * @param session  sesin de hibernate
     * @return Una instancia del objeto recuperado de base de datos o null en el caso de no
     *         encontrar ningn objeto con la clave primaria especificada
     */
    protected <T extends Object> T getByPk(Class<T> theClass, Serializable pk, Session session)
            throws DataAccException {
        log.debug("getByPk");
        T objResult = null;
        try {
            objResult = (T) session.load(theClass, pk);
            log.debug("Objeto con clave '" + pk + "' recuperado");
            return (T) objResult;
        } catch (Exception ex) {
            String msg = "Error recuperando el objeto de tipo '" + theClass + "' con clave primaria '" + pk + "': ";
            log.error("Error recuperando el objeto con clave '" + pk + "': " + msg);
            throw new DataAccException(msg, ex);
        }
    }

    /**
     * Devuelve un objeto de negocio por clave primaria
     *
     * @param pk Una instancia de la clave primaria
     * @return Una instancia del objeto recuperado de base de datos
     */
    protected Object getByPk(Serializable pk) throws DataAccException {
        throw new DataAccException("HibernateManagerBase.getByPk. Mtodo no soportado por esta clase");
    }

    /**
     * Inserta un objeto de negocio en base de datos
     *
     * @param obj a insertar
     */
    public void insert(ITransferObject obj) throws DataAccException {
        log.debug("insert");
        Session session = null;
        try {

            session = HibernateUtil.currentSession();
            session.beginTransaction();
            obj.setOwnerId(SpringUtils.getPrincipal().getId());
            obj.setDepartmentId(SpringUtils.getPrincipal().getDepartmentId());
            Date d = new Date();
            obj.setInsertDate(d);
            obj.setUpdateDate(d);
            session.save(obj);
            Class cls = obj.getClass();
            try {
                if ((Boolean) cls.getField("historial").get(null)) {
                    Historial entrada = new Historial();
                    entrada.setFechaHora(new Date());
                    entrada.setUsuario(SpringUtils.getPrincipal().getUser());
                    entrada.setKlazz(cls);
                    entrada.setIdObjeto(obj.getId());
                    entrada.setTipoCambio(HistorialType.CREADO);
                    session.save(entrada);
                }
            } catch (NoSuchFieldException ex) {
                //pass
            }
            session.getTransaction().commit();
            log.debug("objeto correctamente insertado");
            if (this.cacheable)
                HibernateManagerBase.removeCacheFor(obj.getClass().getName());
        } catch (Exception ex) {
            log.error("insert - exception", ex);
            StringBuffer msg = new StringBuffer("Error insertando el objeto: ");
            msg.append(obj);
            /*
            if(session!=null) {
               session.flush();
               session.close();
            }
            */
            throw new DataAccException(msg.toString(), ex);
        }
        /*finally{
            HibernateUtil.closeSession(session);
        }*/
    }

    /**
     * Actualiza una objeto de negocio en base de datos
     *
     * @param obj el objeto de negocio a actualizar
     */
    public void update(ITransferObject obj, Serializable pk) throws DataAccException {
        log.debug("update");
        Session session = null;
        try {

            session = HibernateUtil.currentSession();
            session.beginTransaction();
            // Cargamos el objeto antiguo
            //IZA         Object objOld = session.load(obj.getClass(), pk);
            log.debug("objeto con clave '" + pk + "' recuperado");
            // Copiamos las propiedades del objeto nuevo al antiguo
            //IZA         BeanUtils.copyProperties(objOld,obj);
            // Actualizamos
            //IZA         session.update(objOld);
            obj.setUpdatedById(SpringUtils.getPrincipal().getId());
            obj.setUpdateDate(new Date());
            //obj = obj.getClass().cast(session.merge(obj));
            try {
                session.update(obj);
            } catch (NonUniqueObjectException ex) {
                session.clear();
                session.update(obj);
            }
            Class cls = obj.getClass();
            try {
                if ((Boolean) cls.getField("historial").get(null)) {
                    Historial entrada = new Historial();
                    entrada.setFechaHora(new Date());
                    entrada.setUsuario(SpringUtils.getPrincipal().getUser());
                    entrada.setKlazz(cls);
                    entrada.setIdObjeto(obj.getId());
                    entrada.setTipoCambio(HistorialType.MODIFICADO);
                    session.save(entrada);
                }
            } catch (NoSuchFieldException ex) {
                //pass
            }
            try {
                session.getTransaction().commit();

                log.debug("objeto con clave '" + pk + "' correctamente actualizado");
                if (this.cacheable)
                    HibernateManagerBase.removeCacheFor(obj.getClass().getName());
            } catch (HibernateException ex) {
                session.getTransaction().rollback();
                session.clear();
            }
        } catch (Exception ex) {
            String msg = "Error actualizando el objeto '" + obj + "' con clave primaria '" + pk + "'";
            log.debug("error actualizando el objeto '" + pk + "': " + msg);
            throw new DataAccException(msg, ex);
        }
        /*finally{
            HibernateUtil.closeSession(session);
        }*/
    }

    public ITransferObject merge(ITransferObject obj) throws DataAccException {
        Serializable pk = obj.getId();
        if (pk == null)
            return obj;

        try {
            Session session = null;
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            log.debug("objeto con clave '" + pk + "' recuperado para mezcla");
            obj = (ITransferObject) session.merge(obj);
            try {
                session.getTransaction().commit();

                log.debug("objeto con clave '" + pk + "' correctamente mezclado");
            } catch (HibernateException ex) {
                session.getTransaction().rollback();
                session.clear();
            }
        } catch (Exception ex) {
            String msg = "Error mezclando el objeto '" + obj + "' con clave primaria '" + pk + "'";
            log.debug("error mezclando el objeto '" + pk + "': " + msg);
            throw new DataAccException(msg, ex);
        }
        return obj;
    }

    /**
     * Elimina un objeto de negocio de base de datos
     *
     * @param obj el objeto de negocio a eliminar
     * @param pk  clave primaria del objeto de negocio a eliminar
     * @deprecated use this method only from derived classes, and use delete() methods in derived classes from other places
     */
    public void delete(Object obj, Serializable pk) throws DataAccException {
        log.debug("delete");
        Class clazz = obj.getClass();
        Session session = null;
        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            // Cargamos el objeto antiguo
            Object objOld = session.load(clazz, pk);
            log.debug("objeto con clave '" + pk + "' recuperado");
            // Borramos
            session.delete(objOld);
            session.getTransaction().commit();
            log.debug("objeto con clave '" + pk + "' correctamente eliminado");
            if (this.cacheable)
                HibernateManagerBase.removeCacheFor(clazz.getName());
            doAfterDelete(pk);
        } catch (Exception ex) {
            StringBuffer msg = new StringBuffer("Error borrando el objeto '");
            msg.append(pk);
            log.debug("error eliminando el objeto '" + pk + "': " + msg.toString());
            throw new DataAccException(msg.toString(), ex);
        }
        /*finally{
            HibernateUtil.closeSession(session);
        }*/
    }

    /**
     * Devuelve todas las ocurrencias de un objeto de negocio
     */
    protected List getAll() throws DataAccException {
        throw new DataAccException("HibernateManagerBase.getAll. Mtodo no soportado por esta clase");
    }

    /**
     * @deprecated use getAll(Class<T> clazz,SortCriteria) instead
     */
    protected <T extends Object> List<T> getAll(String clazz, String[] orderFields) throws DataAccException {
        return (List<T>) getAll(clazz, new SortCriteria(orderFields));
    }

    /**
     * Devuelve todas las ocurrencias de un objeto de negocio. Si est en la cach, la lista
     * la devuelve de la misma y no accede a base de datos
     *
     * @param className de la clase que representa el objeto de negocio que deseamos recuperar
     * @param crit      lista de nombres de campos por los que queremos efectuar la ordenacin
     * @deprecated use getAll(Class<T> clazz,SortCriteria) instead
     */
    protected List getAll(String className, SortCriteria crit) throws DataAccException {
        Session session = null;
        List lResult = null;
        try {
            if (this.cacheable) {
                // Intentamos recuperar la informacin de la cach
                lResult = HibernateManagerBase.getAllFromCache(className);
            }
            if (lResult == null) {
                session = HibernateUtil.currentSession();
                session.beginTransaction();
                // Montamos la query HQL
                StringBuffer query = new StringBuffer("FROM ");
                query.append(className);
                if (crit != null) {
                    query.append(" ");
                    query.append(crit.getHQL());
                }
                lResult = session.createQuery(query.toString()).list();
                session.getTransaction().commit();
                if (this.cacheable) {
                    HibernateManagerBase.updateCache(className, lResult);
                }
            }
            return lResult;
        } catch (Exception ex) {
            String msg = "Error recuperando la lista de objetos de tipo '" + className + "'";
            log.debug(msg);
            throw new DataAccException(msg, ex);
        }
        /*finally{
            HibernateUtil.closeSession(session);
        }*/
    }

    /**
     * Actualiza la cach con un nuevo listado
     *
     * @param className Nombre de la clase cuyo listado se desea actualizar
     * @param list      Lista de objetos que se desea actualizar
     */
    private static synchronized void updateCache(String className, List list) {
        loggerCache.debug("actualizando cach para " + className);
        if (!hasListFor(className))
            // Solo en el caso de que no exista la lista, la guardamos en la cach
            putInCache(className, list);
        loggerCache.debug("cach para " + className + " actualizada");
    }

    /**
     * Pregunta a la cach si tiene una lista para la clase pasada como parmetro
     *
     * @param className Nombre de la clase
     * @return true si ya tiene lista para la clase, o false en caso contrario
     */
    private static synchronized boolean hasListFor(String className) {
        return cache.containsKey(className);
    }

    /**
     * Pone una nueva lista en la cach
     *
     * @param className Nombre de la clase cuyo listado se desea actualizar
     * @param list      Lista de objetos que se desea actualizar
     */
    private static synchronized void putInCache(String className, List list) {
        cache.put(className, list);
        loggerCache.debug("Insertada en la cach la lista de " + className);
    }

    /**
     * Elimina de la cach la lista de objetos de un tipo
     *
     * @param className Nombre de la clase cuyo listado se desea eliminar
     */
    protected static synchronized void removeCacheFor(String className) {
        if (cache.containsKey(className)) {
            cache.remove(className);
            loggerCache.debug("Eliminada la lista de " + className + " de la cach");
        } else
            loggerCache.debug("Se est intentando eliminar " + className
                    + " de la cach y no se encuentra en la misma????");
    }

    /**
     * Devuelve la lista de objetos solicitada
     *
     * @param className Nombre de la clase cuyo listado se desea recuperar
     * @return la lista de objetos, o null en el caso de que no exista dicha lista en cach
     */
    private static synchronized List getAllFromCache(String className) {
        List result = null;
        if (cache.containsKey(className)) {
            result = (List) cache.get(className);
            loggerCache.debug("Recuperada de cach la lista de " + className);
        } else
            loggerCache.debug("No hay lista en cach para " + className);
        return result;
    }

    /**
     * This method is intended to be overriden in order to add specific behavior
     * to be executed after delete an entity.
     *
     * @throws DataAccException
     */
    public void doAfterDelete(Serializable pk) throws DataAccException {
        // Do nothing
    }

}