Implementación de Relaciones Uno a Uno en Hibernate

Seción: Implementación de Relaciones Uno a Uno en Hibernate

Supongamos que un usuario tiene una dirección asociada;

  1. 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:

  1. 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:

Etiquetas: Hibernate Mapeo de Entidades JPA ORM java

Publicado el 6-26 17:20