Hibernate creando una clase genérica | Java

Para poder persistir datos necesitamos una clase genérica que contenga los métodos necesarios, está clase va a servirnos como clase padre de todas las clases DAO (Data Access Object), es decir todas van a heredar de GenericDAO.java para evitar tener que codificar en cada clase los mismo.

Esta clase va a implementar una interfaz generica creada anteriormente.

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.hibernate.Session;
import org.hibernate.Transaction;

public class GenericDAO<T> implements DAO<T> {

    private Class<T> entity;

    private CriteriaBuilder criteriaBuilder;
    private CriteriaQuery<T> criteriaQuery;
    private Root<T> root;
    private TypedQuery<T> typedQuery;

    public GenericDAO(Class<T> entity) {
        this.entity = entity;
    }

    @Override
    public void save(T entity) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.save(entity);
	    transaction.commit();
	} catch (Exception e) {
            if (transaction != null)
	        transaction.rollback();
	    e.printStackTrace();
	}
    }

    @Override
    public void update(T entity) {
        Transaction transaction = null;
	try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
	    session.saveOrUpdate(entity);
	    transaction.commit();
        } catch (Exception e) {
	    if (transaction != null)
	        transaction.rollback();
	    e.printStackTrace();
	}
    }

    @Override
    public void delete(T entity) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
	    transaction = session.beginTransaction();
	    session.delete(entity);
	    transaction.commit();
	} catch (Exception e) {
	    if (transaction != null)
	        transaction.rollback();
	    e.printStackTrace();
	}
    }

    @Override
    public T getById(int id) {
        Transaction transaction = null;
	T object = null;
	try (Session session = HibernateUtil.getSessionFactory().openSession()) {
	    transaction = session.beginTransaction();
	    object = session.get(entity, id);
	    transaction.commit();
	} catch (Exception e) {
	    if (transaction != null)
	        transaction.rollback();
	    e.printStackTrace();
	}
	return object;
    }

    @Override
    public T getById(String id) {
        Transaction transaction = null;
	T object = null;
	try (Session session = HibernateUtil.getSessionFactory().openSession()) {
	    transaction = session.beginTransaction();
	    object = session.get(entity, id);
	    transaction.commit();
	} catch (Exception e) {
	    if (transaction != null)
	        transaction.rollback();
	    e.printStackTrace();
	}
	return object;
    }

    @Override
    public List<T> getAll() {
        Transaction transaction = null;
	List<T> objects = null;
	try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
	    criteriaBuilder = session.getCriteriaBuilder();
	    criteriaQuery = criteriaBuilder.createQuery(entity);
	    root = criteriaQuery.from(entity);
	    typedQuery = session.createQuery(criteriaQuery.select(root));
	    objects = typedQuery.getResultList();
	    transaction.commit();
	} catch (Exception e) {
	    if (transaction != null)
	        transaction.rollback();
	    e.printStackTrace();
	}
	return objects;
    }
}
Con esta clase ya podemos empezar a crear diferentes DAO (Data Access Object) para heredar desde este y por supuesto si crees que hay algún método que pueda ser genérico y se pueda usar con todas las entidades puedes agregarlo primero en la interfaz genérica para después añadirlo en esta clase denominada GenericDAO.java.

En esta clase podemos ver que hacemos uso de HibernateUtil.java que fue creada anteriormente, entonces lo único que se hace aquí es encerrar a la clase Session (en sí es una conexión a la base de datos) para que una vez termine el bloque try se cierre automáticamente sin hacer uso del método close().

También se utiliza clases como: 
  • CriteriaBuilder se utiliza para construir consultas de criterios, selecciones compuestas, expresiones, predicados, ordenaciones)
  • CriteriaQuery<T> lo que hace es tener una consulta mientras se usa, es decir tiene métodos como select, where. Además ten en cuenta que T es la clase que devolverá es decir en este caso sería una entidad, pero también puede devolver una clase String entre otras
  • Root<T> retorna un metamodelo de la entidad, es decir reglas, restricciones, en sí como está estructurada la tabla (entidad) en la base de datos, con que tablas se relaciona entre otros.
  • TypedQuery<T> interfaz utilizada para controlar la ejecución de consultas escritas, en este caso ejecutamos un SELECT al llamar al método getResultList().

← Anterior

Siguiente →

Comentarios

Entradas populares