Saltar a contenido

Semana 5: Entidades en Spring Boot

Introducción

En Spring Boot, una entidad es una clase Java que representa una tabla en una base de datos relacional. Las entidades son fundamentales en aplicaciones que utilizan Spring Data JPA para mapear objetos Java a registros de bases de datos (ORM - Object-Relational Mapping).


¿Qué es una entidad en Spring Boot?

Una entidad es una clase Java anotada con @Entity que se mapea a una tabla en la base de datos. Cada instancia de la entidad representa una fila en la tabla, y los atributos de la clase representan las columnas. Las entidades son gestionadas por el EntityManager de JPA y se utilizan comúnmente con Spring Data JPA para operaciones CRUD.


Anotaciones comunes para entidades

A continuación, se describen las anotaciones más comunes utilizadas en entidades de Spring Boot con JPA, junto con su propósito:

1. @Entity

Indica que la clase es una entidad y debe ser mapeada a una tabla en la base de datos.

  • Uso: Se coloca encima de la clase.
  • Ejemplo: @Entity public class Producto { ... }
  • Nota: La clase debe tener un constructor sin argumentos (puede ser implícito con Lombok).

2. @Table

Especifica el nombre de la tabla en la base de datos a la que se mapea la entidad. Si no se usa, JPA asume que la tabla tiene el mismo nombre que la clase.

  • Atributos comunes:
  • name: Nombre de la tabla.
  • schema: Esquema de la base de datos (opcional).
  • Ejemplo: @Table(name = "productos")

3. @Id

Marca un campo como la clave primaria de la entidad.

  • Uso: Se coloca en el atributo que representa la clave primaria.
  • Ejemplo: @Id private Long id;

4. @GeneratedValue

Define la estrategia para generar automáticamente los valores de la clave primaria.

  • Atributos comunes:
  • strategy: Estrategia de generación (AUTO, IDENTITY, SEQUENCE, TABLE).
  • generator: Nombre del generador personalizado (opcional).
  • Ejemplo: @GeneratedValue(strategy = GenerationType.IDENTITY)
  • Estrategias:
  • AUTO: JPA elige la estrategia según la base de datos.
  • IDENTITY: Usa la funcionalidad de autoincremento de la base de datos.
  • SEQUENCE: Usa una secuencia de base de datos (por ejemplo, en PostgreSQL).
  • TABLE: Usa una tabla auxiliar para generar IDs.

5. @Column

Especifica detalles sobre cómo un atributo se mapea a una columna en la base de datos.

  • Atributos comunes:
  • name: Nombre de la columna.
  • nullable: Indica si la columna permite valores nulos (true o false).
  • length: Longitud máxima para campos de tipo cadena.
  • unique: Indica si la columna debe ser única.
  • Ejemplo: @Column(name = "nombre_producto", nullable = false, length = 100)

6. @Temporal

Se usa para mapear campos de tipo java.util.Date o java.util.Calendar a columnas de tipo fecha o hora en la base de datos.

  • Atributos:
  • TemporalType.DATE: Solo fecha (sin hora).
  • TemporalType.TIME: Solo hora.
  • TemporalType.TIMESTAMP: Fecha y hora.
  • Ejemplo: @Temporal(TemporalType.DATE) private Date fechaCreacion;
  • Nota: Desde Java 8, se recomienda usar LocalDate, LocalTime o LocalDateTime con @Column, ya que son más robustos.

7. @Enumerated

Mapea un campo de tipo enum a una columna en la base de datos.

  • Atributos:
  • EnumType.STRING: Almacena el nombre del enum como cadena.
  • EnumType.ORDINAL: Almacena el índice del enum (0, 1, 2, ...).
  • Ejemplo: @Enumerated(EnumType.STRING) private EstadoProducto estado;

8. @Transient

Indica que un campo no debe ser persistido en la base de datos.

  • Uso: Para campos calculados o temporales.
  • Ejemplo: @Transient private String campoCalculado;

9. Anotaciones de Lombok

Lombok reduce el código repetitivo al generar automáticamente métodos como getters, setters, constructores, etc.

  • @Getter: Genera getters para todos los campos.
  • @Setter: Genera setters para todos los campos.
  • @NoArgsConstructor: Genera un constructor sin argumentos.
  • @AllArgsConstructor: Genera un constructor con todos los argumentos.
  • @ToString: Genera un método toString().
  • @EqualsAndHashCode: Genera métodos equals() y hashCode().
  • @Data: Combina @Getter, @Setter, @ToString, @EqualsAndHashCode y @RequiredArgsConstructor.
  • Ejemplo: @Data public class Producto { ... }

Ejemplo práctico: Entidad Producto

Vamos a crear una entidad Producto que representa un producto en una tienda en línea.

Código de la entidad

package com.tienda.model;

import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDate;

@Entity
@Table(name = "productos")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Producto {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "nombre_producto", nullable = false, length = 100)
    private String nombre;

    @Column(nullable = false)
    private Double precio;

    @Column(name = "fecha_creacion")
    private LocalDate fechaCreacion;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private EstadoProducto estado;

    @Transient
    private String descripcionCompleta;
}

enum EstadoProducto {
    ACTIVO, INACTIVO, DESCONTINUADO
}

Explicación del ejemplo

  • @Entity: Declara la clase como una entidad JPA.
  • @Table(name = "productos"): Mapea la entidad a la tabla productos en la base de datos.
  • @Data: Genera getters, setters, toString(), equals() y hashCode() automáticamente.
  • @NoArgsConstructor y @AllArgsConstructor: Generan constructores sin argumentos y con todos los argumentos, respectivamente.
  • @Id y @GeneratedValue: Definen id como clave primaria con autoincremento.
  • @Column: Especifica detalles de las columnas, como nombres y restricciones.
  • @Enumerated(EnumType.STRING): Almacena el enum EstadoProducto como una cadena en la base de datos.
  • @Transient: El campo descripcionCompleta no se persiste en la base de datos.

Buenas prácticas para entidades

  1. Usar Lombok con moderación: Aunque @Data es útil, considera usar @Getter y @Setter individualmente para controlar qué métodos se generan.
  2. Definir restricciones claras: Usa @Column(nullable = false) y otras restricciones para garantizar la integridad de los datos.
  3. Evitar lógica de negocio en entidades: Las entidades deben ser simples y solo representar datos. La lógica debe ir en servicios.
  4. Usar tipos modernos para fechas: Prefiere LocalDate, LocalDateTime en lugar de java.util.Date.
  5. Nombres explícitos: Usa @Table y @Column para definir nombres claros en la base de datos, evitando conflictos.