El DAO con Spring e Hibernate

1. Información general

Este artículo mostrará cómo implementar DAO con Spring e Hibernate . Para la configuración básica de Hibernate, consulte el artículo anterior de Hibernate 5 con Spring.

2. No más plantillas de primavera

A partir de Spring 3.0 e Hibernate 3.0.1, Spring HibernateTemplate ya no es necesaria para administrar la sesión de Hibernate. Ahora es posible hacer uso de sesiones contextuales: sesiones administradas directamente por Hibernate y activas en todo el alcance de una transacción.

Como consecuencia, ahora es una buena práctica usar la API de Hibernate directamente en lugar de HibernateTemplate. Esto desacoplará efectivamente la implementación de la capa DAO de Spring por completo.

2.1. Traducción de excepciones sin HibernateTemplate

La traducción de excepciones era una de las responsabilidades de HibernateTemplate : traducir las excepciones de Hibernate de bajo nivel a excepciones genéricas de Spring de nivel superior.

Sin la plantilla, este mecanismo todavía está habilitado y activo para todos los DAO anotados con la anotación @Repository . Bajo el capó, esto usa un postprocesador de frijoles Spring que avisará a todos los frijoles @Repository con todo el PersistenceExceptionTranslator que se encuentra en el contexto de Spring.

Una cosa para recordar es que la traducción de excepciones usa proxies. Para que Spring pueda crear proxies alrededor de las clases DAO, estos no deben declararse como finales .

2.2. Gestión de sesiones de hibernación sin la plantilla

Cuando salió el soporte de Hibernate para sesiones contextuales, HibernateTemplate esencialmente se volvió obsoleto. De hecho, el Javadoc de la clase ahora resalta este aspecto (en negrita del original):

NOTA: A partir de Hibernate 3.0.1, el código de acceso transaccional de Hibernate también se puede codificar en estilo Hibernate simple. Por lo tanto, para proyectos recién iniciados, considere adoptar el estilo estándar de Hibernate3 de codificar objetos de acceso a datos en su lugar, basado en {@link org.hibernate.SessionFactory # getCurrentSession ()}.

3. El DAO

Comenzaremos con el DAO base: un DAO abstracto y parametrizado que admite las operaciones genéricas comunes y que podemos extender para cada entidad:

public abstract class AbstractHibernateDAO{ private Class clazz; @Autowired private SessionFactory sessionFactory; public void setClazz(Class clazzToSet) { clazz = clazzToSet; } public T findOne(long id) { return (T) getCurrentSession().get( clazz, id ); } public List findAll() { return getCurrentSession() .createQuery( "from " + clazz.getName() ).list(); } public void save(T entity) { getCurrentSession().persist( entity ); } public T update(T entity) { return (T) getCurrentSession().merge( entity ); } public void delete(T entity) { getCurrentSession().delete( entity ); } public void deleteById(long id) { final T entity = findOne( id); delete( entity ); } protected final Session getCurrentSession(){ return sessionFactory.getCurrentSession(); } }

Algunos aspectos son interesantes aquí: como se discutió, el DAO abstracto no extiende ninguna plantilla Spring (como HibernateTemplate ). En cambio, Hibernate SessionFactory se inyecta directamente en el DAO y tendrá el rol de la API principal de Hibernate, a través de la Session contextual que expone:

this.sessionFactory.getCurrentSession ();

Además, tenga en cuenta que el constructor recibe la Clase de la entidad como parámetro para ser utilizado en las operaciones genéricas.

Ahora, veamos una implementación de ejemplo de este DAO , para una entidad Foo :

@Repository public class FooDAO extends AbstractHibernateDAO implements IFooDAO{ public FooDAO(){ setClazz(Foo.class ); } }

4. Conclusión

Este artículo cubrió la configuración e implementación de la capa de persistencia con Hibernate y Spring.

Se discutieron las razones para dejar de depender de las plantillas para la capa DAO, así como los posibles errores de configurar Spring para administrar transacciones y la sesión de Hibernate. El resultado final es una implementación DAO liviana y limpia, casi sin depender de Spring en tiempo de compilación.

La implementación de este sencillo proyecto se puede encontrar en el proyecto github.