Seción: Implementación de Relaciones Uno a Uno en Hibernate
Supongamos que un usuario tiene una dirección asociada;
- Implementación mediante clave primaria compartida: Usuario.java:
package com.example.modelo;
public class Usuario {
private int identificador;
private String nombre;
private Direccion direccion;
public int getIdentificador() {
return identificador;
}
public void setIdentificador(int identificador) {
this.identificador = identificador;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Direccion getDireccion() {
return direccion;
}
public void setDireccion(Direccion direccion) {
this.direccion = direccion;
}
}
Ver CódigoDireccion.java:
package com.example.modelo;
public class Direccion {
private int identificador;
private String calle;
private String codigoPostal;
private Usuario usuario;
public int getIdentificador() {
return identificador;
}
public void setIdentificador(int identificador) {
this.identificador = identificador;
}
public String getCalle() {
return calle;
}
public void setCalle(String calle) {
this.calle = calle;
}
public String getCodigoPostal() {
return codigoPostal;
}
public void setCodigoPostal(String codigoPostal) {
this.codigoPostal = codigoPostal;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
}
Ver CódigoUsuario.hbm.xml:
<hibernate-mapping package="com.example.modelo">
<class name="Usuario" table="t_usuario">
<id name="identificador" column="idUsuario">
<generator class="native"></generator>
</id>
<property name="nombre" column="nombreUsuario"></property>
<one-to-one name="direccion" class="com.example.modelo.Direccion" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
Direccion.hbm.xml:
<?xml version="1.0"?>
<hibernate-mapping package="com.example.modelo">
<!--
La clave primaria de la tabla t_direccion es la misma que la de t_usuario;
El campo id de t_direccion funciona como clave primaria y como clave foránea.
-->
<class name="Direccion" table="t_direccion">
<id name="identificador" column="idDireccion">
<generator class="foreign">
<param name="property">usuario</param>
</generator>
</id>
<property name="calle" column="calle"></property>
<property name="codigoPostal" column="codigoPostal"></property>
<!-- Configuración de constrained="true" para compartir la clave primaria entre t_direccion y t_usuario -->
<one-to-one name="usuario" class="com.example.modelo.Usuario" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
Código de prueba:
@Test
public void testGuardar1(){
Usuario usuario=new Usuario();
usuario.setNombre("Carlos");
Direccion direccion=new Direccion();
direccion.setCalle("Calle Principal 123");
direccion.setCodigoPostal("01234");
direccion.setUsuario(usuario);
usuario.setDireccion(direccion);
session.save(usuario);
}
Ver CódigoResultado:
La tabla t_direccion tiene un campo idDireccion que sirve como clave primraia y como clave foránea;
Al ejecutar, revisando la base de datos:
- Implementación mediante clave foránea
Usuario2.java:
package com.example.modelo;
public class Usuario2 {
private int identificador;
private String nombre;
private Direccion2 direccion;
public int getIdentificador() {
return identificador;
}
public void setIdentificador(int identificador) {
this.identificador = identificador;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Direccion2 getDireccion() {
return direccion;
}
public void setDireccion(Direccion2 direccion) {
this.direccion = direccion;
}
}
Ver CódigoDireccion2.java:
package com.example.modelo;
public class Direccion2 {
private int identificador;
private String calle;
private String codigoPostal;
private Usuario2 usuario;
public int getIdentificador() {
return identificador;
}
public void setIdentificador(int identificador) {
this.identificador = identificador;
}
public String getCalle() {
return calle;
}
public void setCalle(String calle) {
this.calle = calle;
}
public String getCodigoPostal() {
return codigoPostal;
}
public void setCodigoPostal(String codigoPostal) {
this.codigoPostal = codigoPostal;
}
public Usuario2 getUsuario() {
return usuario;
}
public void setUsuario(Usuario2 usuario) {
this.usuario = usuario;
}
}
Ver CódigoUsuario2.hbm.xml:
<?xml version="1.0"?>
<hibernate-mapping package="com.example.modelo">
<class name="Usuario2" table="t_usuario2">
<id name="identificador" column="idUsuario">
<generator class="native"></generator>
</id>
<property name="nombre" column="nombreUsuario"></property>
<!--
unique="true" asegura que el valor no se repita, es único;
Las claves foráneas normalmente pueden repetirse, pero con unique="true" se logra la unicidad,
implementando así una relación uno a uno
-->
<many-to-one name="direccion" class="com.example.modelo.Direccion2" column="idDireccion" cascade="all" unique="true"></many-to-one>
</class>
</hibernate-mapping>
Ver CódigoDireccion2.hbm.xml:
<hibernate-mapping package="com.example.modelo">
<class name="Direccion2" table="t_direccion2">
<id name="identificador" column="idDireccion">
<generator class="native"></generator>
</id>
<property name="calle" column="calle"></property>
<property name="codigoPostal" column="codigoPostal"></property>
<one-to-one name="usuario" class="com.example.modelo.Usuario2" property-ref="direccion"></one-to-one>
</class>
</hibernate-mapping>
Ver CódigoCódigo de prueba:
@Test
public void testGuardar2(){
Usuario2 usuario=new Usuario2();
usuario.setNombre("María");
Direccion2 direccion=new Direccion2();
direccion.setCalle("Avenida Central 456");
direccion.setCodigoPostal("56789");
direccion.setUsuario(usuario);
usuario.setDireccion(direccion);
session.save(usuario);
}
Ver CódigoEstructura de tablas generadas:
La tabla t_usuario2 tiene una clave foránea idDireccion que referencia la clave primaria de t_direccion2; además, idDireccion tiene una restricción de unicidad;
Registros en la base de datos: