Java tutorial
/** * 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 3 of the License. * * 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, see <http://www.gnu.org/licenses/>. */ /* * HibernateManagerBase.java */ package com.autentia.tnt.dao.hibernate; import java.io.Serializable; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Query; import org.hibernate.Session; import com.autentia.tnt.dao.DataAccException; import com.autentia.tnt.dao.IDataAccessObject; import com.autentia.tnt.dao.ITransferObject; import com.autentia.tnt.dao.SearchCriteria; import com.autentia.tnt.dao.SortCriteria; import com.autentia.tnt.util.HibernateUtil; /** * 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<T extends ITransferObject> implements IDataAccessObject<T> { /** 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 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 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 * @oaram args query parameters * @return a List of Objects with the result * @throws DataAccException */ @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.getSessionFactory().getCurrentSession(); if (!session.getTransaction().isActive()) { 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(); 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.getSessionFactory().getCurrentSession(); objResult = getByPk(theClass, pk, session); return objResult; } /** * Devuelve un objeto de negocio por clave primaria. * * @param obj 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(T obj) throws DataAccException { log.debug("insert"); Session session = null; try { session = HibernateUtil.getSessionFactory().getCurrentSession(); Date d = new Date(); obj.setInsertDate(d); obj.setUpdateDate(d); session.save(obj); log.debug("objeto correctamente insertado"); } catch (Exception ex) { log.error("insert - exception", ex); StringBuffer msg = new StringBuffer("Error insertando el objeto: "); msg.append(obj); throw new DataAccException(msg.toString(), ex); } } /** * 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.getSessionFactory().getCurrentSession(); obj.setUpdateDate(new Date()); session.merge(obj); log.debug("objeto con clave '" + pk + "' correctamente actualizado"); if (this.cacheable) HibernateManagerBase.removeCacheFor(obj.getClass().getName()); } 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); } } /** * Elimina un objeto de negocio de base de datos * @deprecated use this method only from derived classes, and use delete() methods in derived classes from other places * @param obj el objeto de negocio a eliminar * @param pk clave primaria del objeto de negocio a eliminar */ public void delete(Object obj, Serializable pk) throws DataAccException { log.debug("delete"); Class clazz = obj.getClass(); Session session = null; try { session = HibernateUtil.getSessionFactory().getCurrentSession(); // Cargamos el objeto antiguo Object objOld = session.load(clazz, pk); log.debug("objeto con clave '" + pk + "' recuperado"); // Borramos session.delete(objOld); 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); } } /** * 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 * @deprecated use getAll(Class<T> clazz,SortCriteria) instead * @param nombre de la clase que representa el objeto de negocio que deseamos recuperar * @param orderByFieldName lista de nombres de campos por los que queremos efectuar la ordenacin * @param descending si la ordenacion es descendente o ascendente */ 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.getSessionFactory().getCurrentSession(); // 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(); 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); } } /** * 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 cache 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 cache"); } else loggerCache.debug( "Se esta intentando eliminar " + className + " de la cache 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 cache */ private static synchronized List getAllFromCache(String className) { List result = null; if (cache.containsKey(className)) { result = (List) cache.get(className); loggerCache.debug("Recuperada de cache la lista de " + className); } else loggerCache.debug("No hay lista en cache 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 } public void flush() throws DataAccException { try { HibernateUtil.getSessionFactory().getCurrentSession().flush(); } catch (Exception e) { throw new DataAccException("Cant do all action in database.", e); } } }