Creación de una aplicación con Spring e Hibernate desde 0

5
40246

Creación de una aplicación con Spring e Hibernate desde 0

1. Introducción

Como el título reza, en este tutorial vamos a crear una pequeña aplicación usando Spring e Hibernate partiendo desde 0. Este es un tutorial con un enfoque claramente práctico, con lo cual voy a intentar no entrar en conceptos teóricos ni técnicos. Simplemente crearemos unas entidades, unos DAO, una clase con un método main() que ejecute la aplicación y, como no podia ser de otro modo, juntaremos todas las piezas con Spring haciendo uso de su soporte para Hibernate.

 

Para no complicar mucho el ejemplo voy a crear la típica aplicación que accede a una base de datos con información sobre empresas y personal, y para ello usaremos Hibernate con anotaciones, no con mapeos en ficheros .hbm.xml. La aplicación no tiene apenas funcionalidad y se utilizará por consola, pero servirá para ver cómo podemos integrar Hibernate con anotaciones en un proyecto de Spring. Además veremos que gracias al uso de anotaciones es muy sencillo sustituir Hibernate por cualquier otro motor de persistencia que pueda usarse a través de JPA.

 

En adictosaltrabajo ya vemos publicado otros tutoriales sobre Spring e Hibernate que seguramente os sirvan de referencia o como complemento a éste. Si quieres descargar el código fuente de este tutorial no tienes más que pinchar aqui.

 

2. Entorno

 

3. Modelo de datos

El modelo de datos, como se puede observar, es muy sencillo. Tan solo una relación N:M entre COMPANY y WORKER :

 

 

 

El script de creación para MySQL es el siguiente:

 

CREATE DATABASE autentiaSpringHb;
USE autentiaSpringHb;

CREATE TABLE COMPANY (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NOT NULL,
description VARCHAR(255) NOT NULL,
PRIMARY KEY(id)
) engine=innodb default charset=utf8 collate=utf8_spanish_ci;

CREATE TABLE WORKER (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
COMPANY_id INTEGER UNSIGNED NOT NULL,
name VARCHAR(255) NOT NULL,
surname VARCHAR(255) NOT NULL,
workerType VARCHAR(20) NOT NULL,
PRIMARY KEY(id),
CONSTRAINT fk_person_company FOREIGN KEY(COMPANY_id) REFERENCES COMPANY(id)
) engine=innodb default charset=utf8 collate=utf8_spanish_ci;

 

4. Entidades

Para definir las entidades vamos a utilizar las anotaciones de Hibernate, y gracias a ellas nos ahorraremos los .hbm.xml. Como podreis observar viendo los ejemplos es muy sencillo mapear los atributos de las clases y las propias clases, aparte que hace que sea más fácil mantener las clases ya que no tenemos que mantener, aparte de la clase, un fichero xml.

A continuación pego el código del fichero Company.java

Tras ello, el del fichero Worker.java

Como habreis podido observar ambas heredan de AbstractEntity, donde se infieren cosas comunes a las clases mencionadas anteriormente:

Y para rematar, los trabajadores poseen un tipo de trabajador representado con la siguiente clase enumerada:

IMPORTANTE: Daros cuenta de que las anotaciones NO POSEEN ninguna dependencia con Hibernate (todas proceden de javax.persistence). Gracias al uso de estas anotaciones, que forman parte de JPA, podremos cambiar hibernate por cualquier otro ORM que funcione bajo JPA de una manera muy sencilla en los ficheros de configuración de Spring.

 

5. DAO

Otra de las partes que vamos a necesitar en nuestra aplicación son los DAO. Para ello vamos a definir unas interfaces con las operaciones que se puede realizar con ellos y tras eso implementaremos esas interfaces usando el soporte que brinda Spring para Hibernate. Las interfaces son muy simples:

Interfaz CompanyDAO:

Interfaz WorkerDAO:

Interfaz GenericDAO:

Como podeis ver hay una pequeña herencia entre interfaces, ya que tanto WorkerDAO como CompanyDAO heredan de GenericDAO ya que, al fin y al cabo, los métodos save() y delete() borran cualquier tipo de entidad que pueda ser persistida en base de datos.

Una vez comentada la herencia entre interfaces, vamos a por la implementación:

Clase HbSpringCompanyDaoImpl:

Clase HbSpringWorkerDaoImpl:

Clase AbstractHbSpringGenericDaoImpl:

Bueno, como podeis ver tanto los DAO HbSpringCompanyDaoImpl como HbSpringWorkerDaoImpl heredan de AbstractHbSpringGenericDaoImpl, que a su vez hereda de HibernateDaoSupport. ¿Qué conseguimos con esto?. HibernateDaoSupport es una clase de Spring muy simple, y su función es sencillamente dejar más limpio el código de nuestros DAO implementando métodos como el getHibernateTemplate(), que nos permitirá lanzar consultas que usen Hibernate, y otros métodos que permitan la inyección de sesiones de Hibernate desde Spring (en concreto me refiero al método setSessionFactory(), que como ya lo heredamos, no tenemos que implementarlo)

 

6. Configuración de Spring

Tenemos base de datos, tenemos entidades, tenemos DAO, ahora sólo nos falta una cosa, juntarlo todo para poder trabajar con ello. Es aqui donde Spring entra en juego:

Para configurar el datasource indicamos el driver que vamos a usar, cual es la URL de conexión , y cual es el usuario y la clave con las que acceder a la base de datos.

Para configurar Hibernate indicamos el dialecto con el que debe trabajar, cuales son las clases anotadas que debe persistir, y cual es el datasource donde encontrar la conexión con base de datos. Tambien configuraremos el gestor de transacciones.

Finalmente definimos los DAO que vamos a utilizar en la aplicacion y les inyectaremos la factoria de sesiones de Hibernate. Esta factoria es facilitada por Spring, al igual que la clase HibernateDAOSupport.

Si en algún momento quisieramos quitar Hibernate y utilizar otro motor de persistencia deberiamos:

  1. Crear una nueva implementación de los DAO para las interfaces indicadas anteriormente
  2. Cambiar la definición de los DAO que hacemos en Spring (bastaria con cambiar el class=”…”)
  3. Quitar la configuración de Hibernate del fichero de configuración de Spring y configurar el otro motor de persistencia.

Puede parecer mucho, pero si se jerarquizan bien los DAO y se crean pruebas de integración el trabajo de migrar de un motor de persistencia a otro puede ser muy poco, ya que por un lado tendremos que cambiar poco código (si hemos jerarquizado bien) y sabremos que la aplicación funciona en unos momentos (si hemos creado pruebas de integración)

 

7. Ejecución del programa

Para lanzar la aplicación utilizaremos el clásico método main()

Lo que hacemos paso a paso es:

  1. Creamos un contexto a partir del fichero de configuración de Spring. Como podeis ver es una constante con un array de Strings, donde cada fichero de configuración es un String. Esto es, podeis crear tantos ficheros como querais para configurar vuestra aplicación con Spring, aunque yo sólo haya utilizado uno.
  2. Recuperamos los DAO que vamos a utilizar.
  3. Creamos la empresa Autentia y a 3 empleados de ella y los enlazamos.
  4. Tras eso, buscamos en la base de datos y vemos que se han guardado. Ademas durante la ejecución veremos la salida de los System.out que hemos dejado en los DAO a modo de log.

 

8. Conclusiones

Si mirais otra vez el código vereis que hemos escrito poco código y que éste es muy fácil de escribir y mantener, pero que con él hemos conseguido las 4 operaciones básicas sobre base de datos (crear, leer, actualizar y borrar), aunque en el ejemplo solo creemos entidades.

Tambien hemos visto cómo utilizar Spring para juntar todos estos componentes, qué deberiamos hacer para cambiar de motor de persistencia, y cómo hacer para acceder al contexto de Spring desde una clase propia y, desde ella, recuperar los DAO y poder operar con los beans declarados en Spring.

Espero que os sea de utilidad.

 

5 Comentarios

  1. En una segunda pasada, veo que donde más me cuesta seguir el tutorial es en el uso de herencias e interfaces…. a modo de autocrítica. Por lo demás, lo entiendo bien. Creo que ambas tecnologías, Spring e Hibernate, son el pan nuestro de cada día del desarrollo actual.

    Saludos y gracias,
    Jaime.

  2. Raro encontrar tutoriales tan simples pero con alto impacto de contenido y aprendizaje y además bien explicado. Muchas gracias y felicidades, me ha sido de mucha utilidad.

  3. Buenas tardes, yo tengo una relacion n:m hecha con la anotacion @manytomany como vemos en la explicación. Ahora me surge una duda y es como accedo a la clave de tabla que se crea en BBDD con está relación n:m si la clave de dicha tabla está compuesta por la primarykey de cada una de las tablas implicadas más otro campo de tipo numérico? aparte está nueva tabla que surge de dicha relación también tiene más atributos como un fecha por ejemplo.

Dejar respuesta

Please enter your comment!
Please enter your name here