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

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 compartan una única identidad.

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.

Comentarios

Un 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

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

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

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

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

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

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

Aprende cómo migrar tu sitio Joomla 3 a Joomla 5 de forma segura, manteniendo el diseño, la funcionalidad y compatibilidad con extensiones. Una guía paso a paso con recomendaciones, imágenes y buenas prácticas para actualizar sin sorpresas.
Descubre qué es Yocto Project, sus ventajas, usos reales en Izertis y cómo crear tu propia distribución Linux para Raspberry Pi paso a paso, de forma sencilla y flexible.
¿Trabajas con Drupal y SonarQube 9.9? En este artículo exploramos cómo adaptar el análisis estático para evitar falsos positivos, desactivar reglas conflictivas del Quality Profile y delegar el estilo a PHP CodeSniffer. Una guía práctica para mejorar la integración sin depender aún de SonarQube 10.