Hibernate y las anotaciones de EJB 3.0

1
44466

Creación: 14-06-2007

Índice de contenidos

1. Introducción

Hibernate (http://www.hibernate.org/) es una potente herramienta de persistencia que nos permite mapear clases en una base de datos relacional.

Desde la versión 3 Hibernate soporta usar anotaciones de Java 5 para especificar la relación entre las clases y las tablas de la base de datos.

Gracias a las anotaciones conseguiremos librarnos de los ficheros de xml de configuración de los mapeos (los famosos .hbm.xml). De esta manera tendremos que mantener menos ficheros ya que sólo es necesario el .java. Además escribiremos menos, ya que la mayoría de las opciones tienen valores por defecto de forma que en la mayoría de los casos podremos ahorrarnos las anotaciones (bastaría con especificar que la clase es una entidad, cual es el campo identificador y poco más).

Esta forma de trabajar usando los valores por defecto es altamente recomendable, ya que nos ahorramos gran parte de la configuración. Este concepto de «Convención frente a Configuración» seguramente lo hemos odio mucho cuando se trata de Ruby on Rails; y
creo que tienen toda la razón. Debemos intentar trabajar siempre de una misma manera, basándonos en convenciones, esto no sólo nos ahorra tediosos ficheros de configuración, sino que cuando vemos cualquier aplicación ya sabemos que esperara.

Está bien que esté esa configuración para hacer el sistema más flexible y que nos podamos «saltar» esas convenciones cuando realmente sea necesario, porque nos aporta una ventaja real.

«Las normas están para saltárselas» es una frase que me gusta mucho y que suelo usar en mis cursos. Es una frase que tiene más implicaciones de las que pudiera parecer en un principio. No se trata ni mucho menos de un manifiesto anarquista, todo lo contrario, el desarrollo de software debería ser un proceso reglado y disciplinado, con un un conjunto de normas que debemos conocer y respetar. Lo que quiero decir con esta frase es que debemos conocer esas normas, y que si decidimos saltarnos alguna sea porque realmente obtenemos una ventaja de peso, en estos casos esa parte del sistema deberá estar especialmente bien documentada para facilitar el mantenimiento (para que cuando otros vean que nos hemos saltado la norma sepan por qué). Es decir, debemos ser muy conscientes de porque nos saltamos la norma y que implicaciones tiene; lo que no vale, bajo ningún concepto, es hacer las cosas porque sí. Recordar que «el desconocimiento de la ley no exime de su cumplimiento» 😉

(je, je, después de esta pequeña pausa para la evangelización seguimos con las anotaciones de Hibernate 😉

Otra de las principales ventajas de las anotaciones de Hibernate es que son compatibles con las anotaciones de JPA (Java Persistente API, la capa de persistencia de EJB 3.0). Se ve que estos chicos de Hibernate piensan en todo y saben hacer las cosas bien. Gracias a esto podremos usar nuestros POJOs tanto en Hibernate como en EJB3 como en cualquier otro sistema que implemente JPA (por ejemplo en el recién estrenado proyecto de Apache OpenJPA http://openjpa.apache.org/).

Por todo esto no podemos hacer otra cosa que recomendar el uso de las anotaciones. Además la generación de las anotaciones también está soportada por las Hibernate Tools que ya vimos en
https://adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=hibernateTools

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Asus G1 (Core 2 Duo a 2.1 GHz, 2048 MB RAM, 120 GB HD).
  • Sistema Operativo: GNU / Linux, Debian (unstable), Kernel 2.6.21, KDE 3.5
  • Máquina Virtual Java: JDK 1.6.0-b105 de Sun Microsystems
  • Eclipse 3.2.2
  • Hibernate 3.2.2.ga
  • Hibernate Tools 3.2.0 Beta9
  • MySql 5.0.41-2

3. Instalación

Para poder usar las anotaciones de Hibernate, además de los jar de Hibernate, tenemos que dar de alta los jar de Hibernate Annotations en nuesto proyecto.

Si usamos Maven, basta con añadir en nuestro pom.xml

<!-- Para usar Hibernate -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate</artifactId>
    <version>3.2.4.sp1</version>
</dependency>
<!-- Para usar las anotaciones de Hibernate -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-annotations</artifactId>
    <version>3.3.0.ga</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-commons-annotations</artifactId>
    <version>3.3.0.ga</version>
</dependency>

Si no usamos Maven, podemos ir a www.hibernate.org y en la zona de «Download» descargarnos los jar correspondientes.

4. El fichero hibernate.xml.cfg

El fichero de configuración de Hibernate (normalmente hibernate.cfg.xml) cambia poco, aquí vemos un ejemplo:



        jdbc:mysql://localhost:3306/curso
        autentia
        autentia
        org.gjt.mm.mysql.Driver
        org.hibernate.dialect.MySQLInnoDBDialect

            org.hibernate.context.ManagedSessionContext

        true

Antes era típico especificar los «mapping» con el atributo «resource» indicando el fichero xml, ahora usamos el atributo «class» indicando la clase.

El resto del fichero, como veis se mantiene igual.

5. Las clases anotadas

Ahora empieza lo bueno !!!. Tenemos tres clases Campaign, Subcampaign y Budget, donde una campaña puede tener muchas subcampañas, y una subcampaña puede tener muchos presupuestos.

Esto correspondería con el siguiente diagrama UML:

5.1. Campaign (generado por las Hibernate Tools)

package com.autentia.app.persist.hibernate;

// Generated Jun 21, 2007 7:52:14 PM by Hibernate Tools 3.2.0.b9
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Campaign generated by hbm2java
 */
@Entity
@Table(name = "Campaign", catalog = "curso")
public class Campaign implements java.io.Serializable {
    private Long id;
    private String name;
    private Set subcampaigns = new HashSet(0);

    public Campaign() {
    }

    public Campaign(String name) {
        this.name = name;
    }

    public Campaign(String name, Set subcampaigns) {
        this.name = name;
        this.subcampaigns = subcampaigns;
    }

    @Id
    @GeneratedValue
    @Column(name = "id", unique = true, nullable = false)
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name", nullable = false, length = 50)
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "campaign")
    public Set getSubcampaigns() {
        return this.subcampaigns;
    }

    public void setSubcampaigns(Set subcampaigns) {
        this.subcampaigns = subcampaigns;
    }
}

Podemos ver como a nivel de clase indicamos que se trata de una entidad, y la tabla correspondiente.

A nivel de cada «getter» le indicamos con que campo de la tabla corresponde. En este caso especial mención a las anotaciones @Id y @GeneratedValue, que indican cual es el campo clave (la PK), y que sus valores serán generados por la base de datos.

5.2. Campaign (dejando sólo las anotaciones imprescindibles)

package com.autentia.app.persist.hibernate;

// Generated Jun 21, 2007 7:52:14 PM by Hibernate Tools 3.2.0.b9
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Campaign generated by hbm2java
 */
@Entity
public class Campaign implements java.io.Serializable {
    private Long id;
    private String name;
    private Set subcampaigns = new HashSet(0);

    public Campaign() {
    }

    public Campaign(String name) {
        this.name = name;
    }

    public Campaign(String name, Set subcampaigns) {
        this.name = name;
        this.subcampaigns = subcampaigns;
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(mappedBy = "campaign")
    public Set getSubcampaigns() {
        return this.subcampaigns;
    }

    public void setSubcampaigns(Set subcampaigns) {
        this.subcampaigns = subcampaigns;
    }
}

Podemos ver que a nivel de clase ya sólo se está indicando que se trata de una entidad, no hace falta indicar la tabla porque coincide con el nombre de la clase.

A nivel de cada «getter» pasa lo mismo, como el nombre del atributo coincide con el del campo de la tabla, no hace falta poner la anotación. Los atributos como «unique» o «nullable», no son realmente necesarios, estos atributos nos sirven sobre todo si queremos generar el script de creación de la base de datos a partir de las clases anotadas.

Lo que si que tenemos que indicar obligatoriamente es el atributo que hace de PK y la relaciones.

6. Conclusiones

Con Hibernate, las anotaciones y la convención en lugar de la configuración (tomando los valores por defecto), podemos implementar toda la capa de persistencia de nuestras aplicaciones en cuestión de horas. Y si nos apoyamos en Herramientas como las Hibernate Tools, esas horas se pueden convertir en minutos.

Ya sabéis que desde Autentia (www.autentia.com) siempre os aconsejamos desarrollos rápidos y mantenibles. Hibernate se puede convertir en un potente aliado para conseguir estos objetivos.

7. Sobre el autor

Alejandro Pérez García, Ingeniero en Informática (especialidad de Ingeniería del Software)

Socio fundador de Autentia (Formación, Consultoría, Desarrollo de sistemas transaccionales)

mailto:alejandropg@autentia.com

Autentia Real Business Solutions S.L. – ‘Soporte a Desarrollo’

http://www.autentia.com

 

Alejandro Pérez García
Alejandro es socio fundador de Autentia y nuestro experto en Java EE, Linux y optimización de aplicaciones empresariales. Ingeniero en Informática y Certified ScrumMaster. Seguir @alejandropgarci Si te gusta lo que ves, puedes contratarle para darte ayuda con soporte experto, impartir cursos presenciales en tu empresa o para que realicemos tus proyectos como factoría (Madrid). Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación.

1 COMENTARIO

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad