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 29

Preguntas 8

Ordenar por:

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

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;
    }
}
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.

¿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

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

Perfecto, el reto anterior fue cumplido.

Para variables que representan dinero se debe de ocupar Bigdecimal en vez de Double
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

La aparición de `import jakarta` en lugar de `import javax` se debe a la evolución del ecosistema Java. A partir de Jakarta EE 9, las especificaciones de Java EE se transfirieron a la Fundación Eclipse, cambiando el paquete de `javax` a `jakarta`. Esto se realizó para facilitar la gestión y el desarrollo de la plataforma. Si estás utilizando una versión reciente de Spring o cualquier otra tecnología basada en Jakarta EE, es normal que veas esta nueva nomenclatura. Asegúrate de que tu proyecto esté correctamente configurado para trabajar con Jakarta EE.
En mi opinión hubiera sido mejor crear una tabla llamada ventas con el id_venta y relación de OneTomany entre ventas y productos así hubiera mantenido la normalización id_ventas y fk_productos entonces se hubiera hecho un entitye para productos y otro para ventas en donde ventas recibiera un atributo de tipo Producto con las etiquetas @ManyTo
Les recomiendo descargar la libreria Lombok para no escribir los setters y getters. Solo basta con agregar la notación @Data y listo. ![](https://static.platzi.com/media/user_upload/image-aa1859bd-8651-45c7-8e77-0cab2b81237b.jpg) ![](https://static.platzi.com/media/user_upload/image-1d8041b2-873b-4b52-a399-210236d1ba2a.jpg)![](https://static.platzi.com/media/user_upload/image-16e0bd45-7eef-4341-92ca-a46623f43804.jpg)
Porqué si hablamos de que el id del cliente sería la cedula, el cual es un identificador unico, no aplicamos el unique a la columna de ID? al igual que la de correo electronico? Mi Cliente quedó así, lo voy a dejar así a medida que avanza el curso `package com.platzi.curso.persistence.entity;` `import jakarta.persistence.Column;` `import jakarta.persistence.Entity;` `import jakarta.persistence.Id;` `import jakarta.persistence.Table;` `@Entity` `@Table(name="clientes")` `public class Cliente {` ` @Id` ` @Column(name="id", unique = true)` ` private String idCliente;` ` private String nombre;` ` private String apellido;` ` private Long celular;` ` private String direccion;` ` @Column(name = "correo_electronico",unique = true)` ` private String correoElectronico;` ` public String getIdCliente() {` ` return idCliente;` ` }` ` public void setIdCliente(String idCliente) {` ` this.idCliente = idCliente;` ` }` ` public String getNombre() {` ` return nombre;` ` }` ` public void setNombre(String nombre) {` ` this.nombre = nombre;` ` }` ` public String getApellido() {` ` return apellido;` ` }` ` public void setApellido(String apellido) {` ` this.apellido = apellido;` ` }` ` public Long getCelular() {` ` return celular;` ` }` ` public void setCelular(Long celular) {` ` this.celular = celular;` ` }` ` public String getDireccion() {` ` return direccion;` ` }` ` public void setDireccion(String direccion) {` ` this.direccion = direccion;` ` }` ` public String getCorreoElectronico() {` ` return correoElectronico;` ` }` ` public void setCorreoElectronico(String correoElectronico) {` ` this.correoElectronico = correoElectronico;` ` }` `}`
Porque si la relación entre compras y productos es de muchos a muchos, o eso creo. porque no se usa la notación ManyToMany ? Gracias y perdón la ignorancia, soy frontend Senior con muchas ganas de ser fullStack jeje
en que casos se debe implementar la interface Serializable que por lo que se es para que la clase pueda navegar en internet.
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 .