Enrique Viñé Lerma

Consultor tecnológico de desarrollo de proyectos informáticos.

Ingeniero Técnico en Informática por la Universidad Politécnica de Madrid.

Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación

Somos expertos en Java/J2EE

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2009-01-27

Tutorial visitado 15.006 veces Descargar en PDF
Eventos en Hibernate

Eventos en Hibernate (Parte I)

Índice de contenidos

1. Introducción

2. Entorno

3. Preparando una aplicación de ejemplo

3.1. Usando Maven para crear el proyecto

3.2. Creando el modelo

3.3. Creando clases de prueba y probando la aplicación

4. Creando un oyente para escuchar

5. Dos mejor que uno

6. Conclusiones

1. Introducción

Este es el primero de una serie de tutoriales en los que vamos a hablar del manejo de eventos en Hibernate. En este primer tutorial nos vamos a centrar en los oyentes (listeners) que pueden utilizarse con una SessionFactory para capturar los eventos que se producen al cargar una entidad, guardarla, actualizarla, borrarla, etc. y realizar algún tipo de acción en ese momento. En el próximo tutorial veremos cómo asociar métodos de retrollamada en nuestras entidades a determinados eventos, de manera que éstos métodos se ejecutarán al producirse los eventos correspondientes. Esto útlimo además puede hacerse por medio de anotaciones que siguen la especificación de EJB3.

2. Entorno

Para la realización de este tutorial se han utilizado las siguientes herramientas:

  • Hardware: Portátil Asus G50Vseries (Core Duo P8600 2.4GHz, 4GB RAM, 320 GB HD).

  • Sistema operativo: Windows Vista Ultimate.

  • Eclipse Ganymede 3.4.1, con el plugin Q (http://code.google.com/p/q4e) para Maven

  • JDK 1.6.0

  • Maven 2.0.9

  • MySql 5.1.30

  • Hibernate 3

3. Preparando una aplicación de ejemplo

3.1. Usando Maven para crear el proyecto

Para mostrar el uso de los oyentes de eventos vamos a realizar una sencilla aplicación Java que introduzca una serie de usuarios en una base de datos y que después los recupere y los muestre por la salida estándar.

Creamos un nuevo proyecto Maven, al que llamaremos EventosHibernateI, marcamos la casilla para crear un simple proyecto Java y pulsamos finalizar.

Nuevo proyecto Maven

Editamos el fichero pom.xml para añadir las dependencias necesarias para utilizar Hibernate y MySql. Además, cambiamos el nivel de compilación por defecto utilizado por Maven para poder utilizar anotaciones con Hibernate.

3.2 Creando el modelo

Ahora crearemos nuestro modelo, consistente de una única entidad Usuario, la cual será manejada por Hibernate para persistir los usuarios en la base de datos. La entidad tendrá los campos nombre, apellidos, fecha de nacimiento y edad.

El campo edad se marca como Transient para que Hibernate no lo guarde en la base de datos. Este campo será calculado mediante la función "calcularEdad" en base al valor de la fecha de nacimiento. Más adelante veremos como conseguir que está función sea llamada automáticamente al producirse el evento PostLoad, que ocurre justo después de la carga de los datos de la entidad.

Nota: deberemos cambiar el nivel de compilación en Eclipse como mínimo al 1.5, si no lo está ya, para soportar las anotaciones.

Ahora que tenemos una bonita entidad para persistir, vamos a crearnos un simple DAO que nos permita guardar un usuario en la base de datos y recuperar la lista de usuarios.

Añadimos dentro de la carpeta resources el fichero de configuración de Hibernate.

Hemos añadido la propiedad hibernate.hbm2ddl.auto con el valor auto para que Hibernate cree de manera automática las tablas en caso de que no existan. Eso sí, no debemos olvidar crear primero el esquema eventos en la base de datos.

3.3 Creando clases de prueba y probando la aplicación

Ahora crearemos un par de clases para probar el funcionamiento de nuestra aplicación. La primera clase guardará una serie de usuarios en la base de datos. La segunda recuperará la lista de usuarios y mostrará por la consola su nombre, apellidos y edad.

Aquí está el código de nuestra clase PruebaInsercion.

Y aquí tenemos la clase PruebaListado, que mostrará el nombre, apellidos y edad de los usuarios obtenidos de la base de datos.

Ejecutamos primero la inserción y comprobamos que se han añadido correctamente los usuarios a nuestra base de datos:

Listado de usuarios en base de datos

Ahora ejecutamos la prueba de listado y observamos... ¡Cáspita! O todos nuestros usuarios son recién nacidos o creo que hemos cometido algún error ;)

Listado de usuarios con edad igual a cero

Efectivamente, dijimos que íbamos a hacer que la función "calcularEdad" se disparase de forma "automática" al cargar nuestra entidad. ¿Y no era este un tutorial de eventos en Hibernate?.

Hasta ahora sólamente hemos visto el uso normal de Hibernate para persistir entidades. A continuación vamos a ver cómo configurar un oyente para que se ejecute al dispararse un determinado evento.

4. Creando un oyente para escuchar

Una vez preparada nuestra aplicación sólamente nos resta crear una clase oyente que se ejecute al cargar cada entidad Usuario. El oyente se encargará de actualizar el valor de la edad del usuario en función de su fecha de nacimiento.

Los oyentes en Hibernate son en la práctica singletons, por lo que pueden ser compartidos entre peticiones y por tanto no deberían guardar ningún tipo de estado.

Nuestro implementa la interfaz PostLoadEventListener, para capturar este tipo de evento. También podríamos haber extendido la clase PostLoadEvent, el oyente predeterminado de Hibernate.

En Hibernate existem básicamente eventos por cada método de la clase Session (guardar, borrar, buscar...). A continuación se muestra una tabla con todos los eventos existentes:

Evento
Delete PostInsert
DirtyCheck PostLoad
Evict PostUpdate
Flush PreDelete
InitializeCollection PreInsert
Load PreLoad
Lock PreUpdate
Merge Refresh
Persist Replicate
PostDelete SaveOrUpdate

Por cada tipo de evento existe una interfaz, de la forma eventoEventListener y una clase base de Hibernate de la forma eventoEvent. Tanto las interfaces como las clases se encuentran dentro del paquete "org.hibernate.event".

El último paso consiste en asignar el oyente que hemos programado al evento PostLoad, para que se ejecute justo después de cargar las entidades. En nuestro caso sólo existe una entidad, pero un oyente escuchará un evento determinado independientemente de la entidad sobre la que ocurra el mismo. Por tanto debemos ser cuidadosos al utilizar nuestro oyente, asegurándonos de que el evento haya sido producido por la entidad que creemos.

Para configurar nuestro oyente deberemos añadir las siguientes líneas al fichero de configuración de hibernate, dentro de la etiqueta <session-factory>.

Si volvemos a ejecutar la clase que muestra el listado, esta vez obtendremos el resultado esperado:

Listado de usuarios con edades correctas

Esta vez el oyente se ha ejecutado justo después de que se carguen los datos de cada usuario, actualizando el campo edad de los mismos.

5. Dos mejor que uno

¿Y qué pasa si queremos tener varios oyentes para un mismo evento? Simplemente tendremos que añadir el oyente a la pila de oyentes en el fichero de configuración de hibernate. Todos los oyentes serán llamados en su orden de aparición; por esta razón es aconsejable mantener siempre al final de la lista el oyente predeterminado de Hibernate, que podría realizar acciones adicionales.

El fichero de configuración quedaría ahora de la siguiente manera:

Y, por supuesto, deberemos añadir nuestra clase oyente:

Este nuevo oyente aplicará un "lifting" a los usuarios, rejuveneciéndoles 3 años (¡qué maravilla!). Si ejecutamos de nuevo el listado observaremos cómo ha descendido la media de edad de los usuarios.

Listado con usuarios rejuvenecidos 3 años

6. Conclusiones

A la vista de los resultados de este tutorial podemos extraer algunas conclusiones:

  • El uso de oyentes nos permite realizar acciones asociadas a la persistencia de nuestros objetos de manera automática y transparente a nuestra lógica de negocio. Esto nos permite realizar acciones que de otra manera tendríamos que controlar manualmente cada vez que hiciésemos una llamada a la Session de Hibernate.
  • Podemos asignar varios oyentes por cada evento para que realizen diferentes tareas y añadir o quitar oyentes de manera sencilla por medio del fichero de configuración de Hibernate.
  • Deberemos implementar una clase por cada oyente que necesitemos. Estas clases deben implementar la interfaz correspondiente y distinguir en su código de alguna manera la entidad sobre la que se está produciendo el evento.

Ya hemos visto el poder que tienen los eventos para realizar acciones asociadas con la persistencia y alterar los valores de los campos de nuestras entidades. No obstante puede resultar un poco complicado tener que implementar una clase por cada oyente si simplemente lo que queremos es ejecutar un método de la entidad que realice ciertas operaciones sobre sus campos. ¿No sería más sencillo poner simplemente una anotación en el método que queramos ejecutar al producirse un evento?  Responderemos a esta y otras preguntas en la segunda parte de este tutorial.

Y eso es todo. En Autentia siempre estamos buscando soluciones para los problemas que encontramos en nuestro trabajo cotidiano, y esperamos que este y otros de nuestros tutoriales os ayuden también a vosotros a solucionar problemas similares.

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL: