com.google.code.mymon3y.persistencia.dao.hibernate.AbstractGenericHibernateDAO.java Source code

Java tutorial

Introduction

Here is the source code for com.google.code.mymon3y.persistencia.dao.hibernate.AbstractGenericHibernateDAO.java

Source

/*
 * Copyright (C) 2009
 * 
 * Jaindson Valentim Santana (jaindsonvs [at] gmail [dot] com)
 * Matheus Gaudencio do Rgo (matheusgr [at] gmail [dot] com)
 * 
 * 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 any later version.
 * You may obtain a copy of the License at
 *
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * 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.
 * 
 */
package com.google.code.mymon3y.persistencia.dao.hibernate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.validator.InvalidStateException;

import com.google.code.mymon3y.model.Identificavel;
import com.google.code.mymon3y.persistencia.HibernateFactory;
import com.google.code.mymon3y.persistencia.InvalidPropertiesException;
import com.google.code.mymon3y.persistencia.PersistenciaMyMon3yException;
import com.google.code.mymon3y.persistencia.dao.Comando;
import com.google.code.mymon3y.persistencia.dao.GenericDAO;

/**
 * DAO genrico do Hibernate.
 * 
 * @author Jaindson Valentim Santana
 * @author Matheus Gaudencio do Rgo
 * 
 */
public abstract class AbstractGenericHibernateDAO<T extends Identificavel, ID extends Serializable>
        implements GenericDAO<T, ID> {

    /**
     * Sesso utilizada pela Conexo.
     */
    protected Session session;

    /**
     * Uma transao a ser efetuada em cada interao com o banco.
     */
    protected Transaction tx;

    /**
     * Classe do Objeto estendendo a classe abstrata.
     */
    protected Class<T> persistentClass;

    /**
     * Construtor simples da classe abstrata
     */
    @SuppressWarnings("unchecked")
    public AbstractGenericHibernateDAO() {

        HibernateFactory.buildSeNecessario();
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
    }

    /**
     * Retorna a seo atualmente em uso.
     * 
     * @return A seo atualmente em uso.
     */
    protected Session getSession() {

        return session;
    }

    /**
     * Retorna a transao atualmente em uso.
     * 
     * @return A transao atualmente em uso.
     */
    protected Transaction getTransaction() {

        return tx;
    }

    /**
     * Retorna a instancia da classe que estende a classe abstrata.
     * 
     * @return A instancia da classe que estende a classe abstrata.
     */
    public Class<T> getPersistentClass() {

        return persistentClass;
    }

    /**
     * Operaes a serem realizadas com a entidade antes dela ser apagada e com a sesso ainda aberta.
     * 
     * @param entity
     *            Entidade a ser apagada.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    protected void fazerAntesDeApagarSessaoAberta(T entity) throws PersistenciaMyMon3yException {

        verificarInconsistenciasAntesDeApagarSessaoAberta(entity);
    }

    /**
     * Operaes a serem realizadas com a entidade depois dela ser apagada e com a sesso ainda aberta.
     * 
     * @param entity
     *            Entidade a ser apagada.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    protected void fazerDepoisDeApagarSessaoAberta(T entity) throws PersistenciaMyMon3yException {

    }

    /**
     * Operaes a serem realizadas antes de carregar uma entidade e com a sesso j aberta.
     * 
     * @param entity
     *            Entidade a ser carregada.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    protected void fazerAntesDoLoadSessaoFechada(T entity) throws PersistenciaMyMon3yException {

    }

    /**
     * Operaes a serem realizadas antes de persistir uma entidade e com a sesso ainda aberta.
     * 
     * @param entity
     *            Entidade a ser persistida.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    protected void fazerAntesDePersistirSessaoAberta(T entity) throws PersistenciaMyMon3yException {

        verificarInconsistenciasAntesDePersistirSessaoAberta(entity);

    }

    /**
     * Verificar consistncia da entidade antes de persistir e com a sesso ainda aberta.
     * 
     * @param entity
     *            Entidade a ser persistida.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    protected void verificarInconsistenciasAntesDePersistirSessaoAberta(T entity)
            throws PersistenciaMyMon3yException {

    }

    /**
     * Verificar consistncia da entidade antes de apagar e com a sesso ainda aberta.
     * 
     * @param entity
     *            Entidade a ser apagada.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    protected void verificarInconsistenciasAntesDeApagarSessaoAberta(T entity) throws PersistenciaMyMon3yException {

    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#makeTransient()
     */
    public void makeTransient() throws PersistenciaMyMon3yException {

        try {
            startOperation();
            getSession().createQuery("delete " + getPersistentClass().getSimpleName()).executeUpdate();
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }

    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#makePersistent(com.google.code.mymon3y.model.Identificavel)
     */
    public T makePersistent(T entity) throws PersistenciaMyMon3yException {

        try {
            startOperation();
            fazerAntesDePersistirSessaoAberta(entity);
            getSession().saveOrUpdate(entity);
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        return entity;
    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#makePersistent(java.util.List)
     */
    public List<T> makePersistent(List<T> entidades) throws PersistenciaMyMon3yException {

        List<T> result = entidades;
        try {
            startOperation();
            for (T entity : entidades) {
                fazerAntesDePersistirSessaoAberta(entity);
                getSession().saveOrUpdate(entity);
            }
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        return result;
    }

    /**
     * @see #makePersistent(List)
     */
    public List<T> makePersistent(T... entidades) throws PersistenciaMyMon3yException {

        List<T> lista = new ArrayList<T>(entidades.length);
        CollectionUtils.addAll(lista, entidades);
        return makePersistent(lista);
    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#makeTransient(com.google.code.mymon3y.model.Identificavel)
     */
    public void makeTransient(T entity) throws PersistenciaMyMon3yException {

        try {
            startOperation();
            fazerAntesDeApagarSessaoAberta(entity);
            getSession().delete(entity);
            fazerDepoisDeApagarSessaoAberta(entity);
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#makeTransient(java.util.List)
     */
    public void makeTransient(List<T> entidades) throws PersistenciaMyMon3yException {

        try {
            startOperation();
            for (T entity : entidades) {
                fazerAntesDeApagarSessaoAberta(entity);
                getSession().delete(entity);
                fazerDepoisDeApagarSessaoAberta(entity);
            }
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }

    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#makeTransient(java.io.Serializable)
     */
    public void makeTransient(ID id) throws PersistenciaMyMon3yException {

        T t = findById(id);
        makeTransient(t);
    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#findById(java.io.Serializable)
     */
    @SuppressWarnings("unchecked")
    public T findById(ID id) throws PersistenciaMyMon3yException {

        T entity = null;
        try {
            startOperation();
            entity = (T) getSession().get(getPersistentClass(), id);
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        fazerAntesDoLoadSessaoFechada(entity);
        return entity;
    }

    /**
     * Executa uma operao envolvendo o banco de dados de forma segura (sesso aberta, controle de transao, etc.).
     * 
     * @param comando
     *            Comando a ser executado.
     * @return Objeto de retorno do Comando executado.
     * @throws PersistenciaMyMon3yException
     *             Caso algum erro de persistncia ocorra.
     */
    public Object executarOperacao(Comando comando) throws PersistenciaMyMon3yException {

        Object result = null;
        try {
            startOperation();

            result = comando.executar();

            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        return result;
    }

    /**
     * @see com.google.code.mymon3y.persistencia.dao.GenericDAO#findAll()
     */
    @SuppressWarnings("unchecked")
    public List<T> findAll() throws PersistenciaMyMon3yException {

        List<T> result = null;
        try {
            startOperation();
            result = getSession().createQuery("from " + getPersistentClass().getSimpleName()).list();
            getSession().flush();
            getTransaction().commit();
        } catch (HibernateException e) {
            handleException(e);
        } catch (RuntimeException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        for (T t : result) {
            fazerAntesDoLoadSessaoFechada(t);
        }
        return result;

    }

    /**
     * Faz o rollback da transao sendo utilizada no momento em que houve o lanamento da exceo e relana como uma
     * Exceo do tipo {@link PersistenciaMyMon3yException} conhecida pela Aplicao.
     * 
     * @param e
     *            Exceo a ser tratada.
     * @throws PersistenciaMyMon3yException
     *             Exceo a ser lanada encapsulando a exceo de mais baixo nvel que ocorreu.
     */
    protected void handleException(HibernateException e) throws PersistenciaMyMon3yException {

        HibernateFactory.rollback(tx);
        throw getException(e);
    }

    /**
     * Faz o rollback da transao sendo utilizada no momento em que houve o lanamento da exceo e relana como uma
     * Exceo do tipo {@link PersistenciaMyMon3yException} conhecida pela Aplicao.
     * 
     * @param e
     *            Exceo a ser tratada.
     * @throws PersistenciaMyMon3yException
     *             Exceo a ser lanada encapsulando a exceo de mais baixo nvel que ocorreu.
     */
    private void handleException(RuntimeException e) throws InvalidPropertiesException {
        HibernateFactory.rollback(tx);
        throw getException(e);
    }

    /**
     * Retorna uma exceo do tipo {@link PersistenciaMyMon3yException}.
     * 
     * @param e
     *            Exceo {@link HibernateException} que ocorreu.
     * @return Uma exceo do tipo {@link PersistenciaMyMon3yException}.
     */
    protected PersistenciaMyMon3yException getException(HibernateException e) {

        return new PersistenciaMyMon3yException(e);
    }

    /**
     * Retorna uma exceo do tipo {@link InvalidPropertiesException} caso a exceo {@link RuntimeException} lanada
     * seja do tipo {@link InvalidStateException}.
     * 
     * @param e
     *            Exceo {@link RuntimeException} que ocorreu.
     * @return Uma exceo do tipo {@link InvalidPropertiesException} caso a exceo {@link RuntimeException} lanada
     *         seja do tipo {@link InvalidStateException}.
     */
    private InvalidPropertiesException getException(RuntimeException e) {
        if (e instanceof InvalidStateException) {
            InvalidStateException ise = (InvalidStateException) e;
            return new InvalidPropertiesException(ise.getInvalidValues());
        }
        throw e;
    }

    /**
     * Inicializa as entidades necessrias para se fazer uma operao no banco de dados.
     * 
     * @throws PersistenciaMyMon3yException
     *             Exceo lanada caso haja algum erro de persistncia.
     */
    protected void startOperation() throws PersistenciaMyMon3yException {

        if (session == null || !session.isOpen()) {
            session = HibernateFactory.openSession();
        }
        tx = session.beginTransaction();
    }

}