No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Java Spring

Curso de Java Spring

Alejandro Ramírez

Alejandro Ramírez

Crear Entity cuando su clave primaria es compuesta

14/35
Recursos

Aportes 24

Preguntas 8

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Solo aprovecho para mencionar a todos aquellos que estan aprendiendo Java en este curso, que aunque para este ejemplo está bien, para un aplicativo real, no se deberían usar atributos de tipo Float o Double para almacenar datos monetarios (precios, totales, intereses, impuestos, etc.) sino el tipo de dato BigDecimal. Hay muchos artículos que explican el motivo, por ejemplo: https://dzone.com/articles/never-use-float-and-double-for-monetary-calculatio

Abro debate: Llaves compuestas es una mala practica si tienes campos adicionales en la tabla. . Si quieres relacionar muchos a muchos y tienes más campos adicionales para esa tabla, entonces se sugiere crear una PK única y te evitas mil pasos. . Si quieres relacionar muchos a muchos y no tienes mas campos adicionales que añadir, entonces haz la llave compuesta y haz una relación muchos a muchos.

Cuando se tiene una tabla en la que su llave primara es compuesta, se debe hacer una clase aparte que contenga los atributos que conforman la llave

Creando la Clase que tendra nuestra llave compuesta
Recuerda que debe de contener lo siguiente:


  • se le debe agregar la anotacion @Embeddable
  • se debe de hacer un “implements Serializable”
  • debe contener los atributos que conformen la llame compuesta
  • como en la mayoria de entidades debemos crear los getter y setters
@Embeddable
public class ComprasProductoPK implements Serializable {
    @Column(name = "id_compra")
    private Integer idCompra;

    @Column(name = "id_producto")
    private Integer idProducto;

    public Integer getIdCompra() {
        return idCompra;
    }

    public void setIdCompra(Integer idCompra) {
        this.idCompra = idCompra;
    }

    public Integer getIdProducto() {
        return idProducto;
    }

    public void setIdProducto(Integer idProducto) {
        this.idProducto = idProducto;
    }
}

En la clase principal debemos tener:

  • Declarar la variable id como el tipo de la clase que creamos de nuestra llave compuesta que en este caso es : “ComprasProductoPK”
  • Agregarle la etiqueta @EmbeddeId que hace referencia a que es una llave compuesta y que esta dada por otra clase
  • Y nuevamente los Getter y Setters
@Entity
@Table(name = "compras_productos")
public class ComprasProducto {
    @EmbeddedId
    private ComprasProductoPK id;
private Integer cantidad;
private Double total;
private Boolean estado;

    public ComprasProductoPK getId() {
        return id;
    }

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

    public Integer getCantidad() {
        return cantidad;
    }

    public void setCantidad(Integer cantidad) {
        this.cantidad = cantidad;
    }

    public Double getTotal() {
        return total;
    }

    public void setTotal(Double total) {
        this.total = total;
    }

    public Boolean getEstado() {
        return estado;
    }

    public void setEstado(Boolean estado) {
        this.estado = estado;
    }
}

¿Por qué usamos tipos objetos como “Integer” y no su tipo primitivo “int”? ¿Se utilizarán posteriormente métodos de la clase “Integer”?

¿No es una mala practica tener una tabla con dos llaves primarias?
Cuando se usan tablas relacionales lo usual es que esta tabla tenga su propio id, eso es lo que tengo entendido de los cursos previos de SQL.

Luego de colocar el implements Serializable, VSCode me marca un error y para resolverlo, el quick fix me sugiere que le agregue la línea:
private static final long serialVersionUID = 1L;
Podrías explicarnos por qué solicita esta línea?

Las anotaciones de lombok funcionan para mapear objetos de la base de datos?

Utilizando @JoinColumn y @ManyToOne

Perfecto, el reto anterior fue cumplido.

Para variables que representan dinero se debe de ocupar Bigdecimal en vez de Double

Manera sencilla de implementar Setter y Getter

El código es mas limpio y fácil de leer
Toda la clase es como se ve en la imagen (Así de sencillo)

  • O Lo implementan de esta manera

  • Y luego incluyen las anotaciones @Setter y Getter para generar los metodos
implements Serializable

tiene que ver con la serialización de objetos:
La serialización de un objeto consiste en generar una secuencia de bytes lista para su almacenamiento o transmisión. Después, mediante la deserialización, el estado original del objeto se puede reconstruir. Mas info aquí

JPA ofrece un plugin para intelliJ el cual se llama JPA Support, este plugin es capaz de leer la estructura de las tablas en tu base de datos y de acuerdo a eso, mapear las entidades a código java JPA.
sin embargo, es necesario revisar que las relaciones en las tablas si queden correctamente.
Esto te puede ayudar a ahorrar tiempo en el mapeo de entidades si ya tienes muy interiorizado el funcionamiento JPA.

La alternativa a esto seria usar @ManyToMany o @ManyToOne?

Para los getters y setters, se puede usar lombok
https://projectlombok.org/

@Embeddable
Vamos a definir nuestra clase ComprasProductoPK en esta sección. El autor y el nombre especificarán id_compra y id_producto que serán los dos id dentro de nuestra clase: la clase es Serializable e implementa métodos equals y hashCode

@EmbeddedId
Nuestra entidad ComprasProducto en la variable id (de tipo ComprasProductoPK) toma @EmbeddedId para tomar los valores dentro de ComprasProductoPK el cual indica a JPA que la entidad ComprasProducto tiene una clave compuesta

Consulta, Alguna forma de evitar estos warning al momento de correr el servicio. para la clase ComprasProductoPK ```js HHH000038: Composite-id class does not override equals(): com.platzimarket.persistence.entity.ComprasProductoPK HHH000039: Composite-id class does not override hashCode(): com.platzimarket.persistence.entity.ComprasProductoPK ```busque algunas explicaciones de estos warn y no fueron muy claras. saludos.

Para los que deseen aquí pueden encontrar mis notas hasta este momento en la sección de Spring y JPA

😃

Muy interesante.

package com.test.market.persistence.entity;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;

// Se usa la notación embeddable porque después se embede en la otra clase
@Embeddable
public class ComprasProductoPK implements Serializable {
    @Column(name = "id_compra")
    private Integer idCompra;

    @Column(name = "id_producto")
    private Integer idProducto;

    public Integer getIdCompra() {
        return idCompra;
    }

    public void setIdCompra(Integer idCompra) {
        this.idCompra = idCompra;
    }

    public Integer getIdProducto() {
        return idProducto;
    }

    public void setIdProducto(Integer idProducto) {
        this.idProducto = idProducto;
    }
}

mapeo n-n

no habia algo q te sacaba el mapeado solo? o me equivoquo

Con el implements Serializable, en VS Code me marca un error, y para resolverlo fue necesario colocar la siguiente linea: private static final long seriaVersionUID = 1L;

en mi ejercicio tengo una restricción única compuesta y la coloqué así: uniqueConstraints={
@UniqueConstraint(columnNames = {“documentoIdentificacionArrendatario”, “codigoInmueble”})
}
cabe aclarar que solo estoy trabajando con una tabla .