Uso de las anotaciones @Embeddable, @Embedded, @AttributeOverrides, @AssociationOverrides

1
31485

Uso de las anotaciones @Embeddable, @Embedded, @AttributeOverrides, @AssociationOverrides

0. Índice de contenidos.


1. Introducción

En ocasiones, cuando trabajamos con herramientas de mapeo objeto-relacional, como por ejemplo Hibernate, puede ser interesante la inclusión de entidades dentro de otras entidades de tal forma que las dos (o varias entidades) compartan una única identidad.

En este tutorial vamos a describir como realizar ese objetivo con cuatro simples anotaciones.

2. Entorno

  • Mackbook Pro
    • Intel Core i7 2Ghz
    • 8GB RAM
    • 500GB HD
    • Sistema Operativo: Mac OS X (10.6.8)

3. Descripción de las anotaciones.

A continuación vamos a describir las cuatro anotaciones que vamos a necistar para incrustar una entidad dentro de otra.

Como nota, las cuatro anotaciones pertenecen al paquete javax.persistence.

  • @Embeddable : Con esta anotación, indicamos que la clase puede ser «integrable» dentro de una entidad.
  • @Embedded : Con esta anotación, indicamos que el campo o la propiedad de una entidad es una instancia de una clase que puede ser integrable. Es decir, para que funcione, el campo que hayamos anotado como @Embedded, debe corresponderse con una clase que tenga la anotación @Embeddable.
  • @AttributeOverrides : Con esta anotación, podemos sobreescribir o redefinir el mapeo de campos o propiedades de tipo básico. Esta anotación recibe un array de @AttributeOverride

    • @AttributeOverride: Con esta anotación, podemos redefinir el mapeo de tipos básicos. Su uso es @AttributeOverride(name=»atributoDeLaClaseEmbebida», column = @Column(name=»nombreColumnaEnLaTabla»)),
  • @AssociationOverrides : Con esta anotación, podemos sobreescribir o redefinir el mapeo de campos o propiedades complejos. Esta anotación recibe un array de @AssociationOverride

    • @AssociationOverride: Con esta anotación, podemos redefinir el mapeo de tipos básicos. Su uso es @AssociationOverride(name=»atributoDeLaClaseEmbebida»,joinColumns=@JoinColumn(name=»columna_id»)), donde el primer parámetro es el nombre del atributo de la clase embebida que estamos redefiniendo, y el seguno parámetro es un @JoinColumn, en donde podemos especificar por que campo hacemos el join.

4. Ejemplos

Ahora que ya sabemos para que se usa cada anotación, vamos a ver unos ejemplos de como podemos usarlas. Los ejemplos buscan más una manera de mostrar el uso de las anotaciones de una forma práctica que mostrar un escenario completamente real.

Tenemos una clase Coche.java en donde vamos a incrustar dos atributos de la misma clase Asiento.java. La definición principal de las dos clases es:

package com.adictosaltrabajo.tutoriales;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Coche {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	Motor motor;
		
	public Coche() {
		// TODO Auto-generated constructor stub
	}
	
	public Integer getId() {
		return id;
	}
	
	public void setId(Integer id) {
		this.id = id;
	}

	public Motor getMotor() {
		return motor;
	}
	
	public void setMotor(Motor motor) {
		this.motor = motor;
	}
}

package com.adictosaltrabajo.tutoriales;


public class Asiento {

	int pesoMaximoEnKg;
	
	//Clase compleja
	Cinturon cinturon;
	
	public Asiento() {
		// TODO Auto-generated constructor stub
	}
	
	public int getPesoMaximoEnKg() {
		return pesoMaximoEnKg;
	}
	
	public void setPesoMaximoEnKg(int pesoMaximoEnKg) {
		this.pesoMaximoEnKg = pesoMaximoEnKg;
	}
	
	public Cinturon getCinturon() {
		return cinturon;
	}
	
	public void setCinturon(Cinturon cinturon) {
		this.cinturon = cinturon;
	}
}


Si ahora queremos que las dos clases sean una única entidad, utilizamos las anotaciones que hemos comentado anteriormente: @Embeddable y @Embedded.
NOTA: solo se muestra el código referente a los cambios realizados.

@Entity
public class Coche {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	Motor motor;
	
	@Embedded //Anotamos para indicar que es una propiedade embebida.
	Asiento asientoConductor;
		
	public Coche() {
		// TODO Auto-generated constructor stub
	}
	.......................
import javax.persistence.Embeddable;

@Embeddable  //Anotamos para indicar que es una clase que se puede incrustar.
public class Asiento {

	int pesoMaximoEnKg;
	
	//Clase compleja
	Cinturon cinturon;
	
	public Asiento() {
	......................

¿Que ocurre si ahora queremos meter otro asiento?

	@Embedded
	Asiento asientoConductor;
	
	@Embedded
	Asiento asientoCopiloto;
		
	public Coche() {
	.....................

pues hibernate nos lanzará una excepción (org.hibernate.MappingException) indicando que hay columnas repetidas

Para solucionarlo, lo que tenemos que hacer es indicar a Hibernate como queremos realizar el mapeo de la clase usando las dos anotaciones que nos faltan por usar del tutorial ;), @AttributeOverrides y @AssociationOverrides

La clase Asiento.java, tiene dos atributos, «pesoMaximoEnKg» que es de tipo básico (int) y «cinturon» que pertenece a un tipo complejo Cinturon. Entonces hemos de indicar como mapear los dos atributos de forma que pertenezcan a columnas diferentes en la tabla de la baes de datos.

	
	@Embedded
	@AttributeOverrides(  {
		@AttributeOverride(name="pesoMaximoEnKg", column = @Column(name="pesoMaximoEnKgConductor")),
	}
	@AssociationOverrides({
		@AssociationOverride(name="cinturon",joinColumns=@JoinColumn(name="cinturonConductor_id")),
	})
	Asiento asientoConductor;
	
	@Embedded
	@AttributeOverrides(  {
		@AttributeOverride(name="pesoMaximoEnKg", column = @Column(name="pesoMaximoEnKgCopiloto")),
	}
	@AssociationOverrides({
		@AssociationOverride(name="cinturon",joinColumns=@JoinColumn(name="cinturonCopiloto_id")),
	})
	Asiento asientoCopiloto;
		
	public Coche() {
		// TODO Auto-generated constructor stub
	}
	........................


5. Conclusiones

Hemos visto en el tutorial que sólo con el uso de anotaciones, somos capaces de incrustar clases dentro de entidades para que se comporten con una única identidad. Esto nos puede servir para agrupar varias clases con un contexto similar, para hacer más legible el código y para muchas cosas más.

Para cualquier comentario, duda o sugerencia, tenéis el formulario que aparece a continuación.

Un saludo.

1 COMENTARIO

  1. Una consulta por favor si me pudiera ayudar con un problema que se me esta presentando en hibernate con anotaciones mixing nullable is not allow in column null , el problema se ve reflejado cuando se quiere crear el sessionFactory y el mapeo inicia la lectura del mapeo y se encuentra con una relacion de uno a muchos en donde la relacion de uno es una clave compuesta y esta hace referencia a un fk con los dos campos de la clave compuesta y estos campos donde son foraneos pueden ser nulos entonce leyendo un poco me encontre con que podia agragar nullnable = false a todas.

    al cambiar la configuracion se arreglo el problema de las session factory ya deja trabajar. pero al momento de insertar un registro en la tabla que me debe de permitir los valores nulos estos no se insertan es mas le agregue al mapeo un sql true y el insert que hace hibernate lo envia sin esos campos favor su ayuda porque ya estoy muchos dias con este problema.

    mi correo es oscar_obandoc@hotmail.com cualquier ayuda es importante.

    Gracias,

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