Volver a la página principal
viernes 11 octubre 2024
83

Cómo definir un enum en una entidad con springboot

¿Qué es un enum y cuándo usarlo?

Un enum es una clase especial en Java que representa un grupo de constantes (variables que no cambian). Por ejemplo, se puede usar para definir tipos de roles (ADMIN, USER, GUEST), estados (PENDING, APPROVED, REJECTED), o días de la semana (MONDAY, TUESDAY, etc.). Los enums ayudan a crear código más limpio y seguro, ya que permiten restringir los posibles valores de una variable a un conjunto predefinido.

En una aplicación Spring Boot, los enums se pueden usar dentro de entidades para representar valores en columnas de bases de datos. Sin embargo, es importante tener en cuenta cómo mapear estos enums correctamente a la base de datos utilizando JPA (Java Persistence API).

¿Cómo definir un enum en una entidad de Spring Boot?

Veamos cómo implementar un enum paso a paso. Utilizaremos un ejemplo práctico de una entidad llamada Order que tiene un campo status que será de tipo OrderStatus.

Paso 1: Definir el enum

Primero, definimos el enum en un archivo separado o dentro de la entidad, dependiendo de la complejidad del proyecto. Para este ejemplo, crearemos un enum llamado OrderStatus con tres estados diferentes: PENDING, SHIPPED y DELIVERED.

public enum OrderStatus {
    PENDING,
    SHIPPED,
    DELIVERED
}

Paso 2: Crear la entidad con el campo enum

A continuación, creamos una entidad llamada Order que utiliza este enum como uno de sus campos. Utilizaremos la anotación @Enumerated para indicar que este campo es de tipo enum. Por defecto, JPA almacena los enum en la base de datos como un valor ordinal (0, 1, 2), pero esto no es recomendable ya que puede causar problemas de legibilidad y mantenimiento. En su lugar, es mejor utilizar la opción EnumType.STRING para guardar el nombre del enum como un String en la base de datos.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Enumerated;
import javax.persistence.EnumType;

@Entity
public class Order {

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

    private String product;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    // Constructores, getters y setters

    public Order() {}

    public Order(String product, OrderStatus status) {
        this.product = product;
        this.status = status;
    }

    public Long getId() {
        return id;
    }

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

    public String getProduct() {
        return product;
    }

    public void setProduct(String product) {
        this.product = product;
    }

    public OrderStatus getStatus() {
        return status;
    }

    public void setStatus(OrderStatus status) {
        this.status = status;
    }
}

Paso 3: Configurar el repositorio

El siguiente paso es crear el repositorio JPA para nuestra entidad Order. Esto se hace extendiendo la interfaz JpaRepository que proporciona métodos CRUD por defecto. No es necesario hacer ninguna configuración especial para los campos enum en el repositorio.

import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long> {
}

Paso 4: Usar el enum en controladores y servicios

Ahora que tenemos nuestra entidad y repositorio configurados, podemos usar el enum en los servicios y controladores para gestionar los diferentes estados de las órdenes. Aquí hay un ejemplo de cómo cambiar el estado de una orden a SHIPPED en un servicio:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    public void shipOrder(Long orderId) {
        Order order = orderRepository.findById(orderId)
                        .orElseThrow(() -> new RuntimeException("Order not found"));
        order.setStatus(OrderStatus.SHIPPED);
        orderRepository.save(order);
    }
}

Paso 5: Realizar consultas basadas en el enum

Es posible realizar consultas basadas en el valor del enum usando métodos de consulta de Spring Data JPA. Por ejemplo, para encontrar todas las órdenes con estado PENDING, se puede definir un método en el repositorio como:

import java.util.List;

public interface OrderRepository extends JpaRepository<Order, Long> {
    List<Order> findByStatus(OrderStatus status);
}

Y luego invocar este método en un servicio o controlador para recuperar las órdenes pendientes:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderRepository orderRepository;

    @GetMapping("/pending")
    public List<Order> getPendingOrders() {
        return orderRepository.findByStatus(OrderStatus.PENDING);
    }
}

Consideraciones adicionales

  • Persistencia de enum como valor ordinal: Aunque es posible usar EnumType.ORDINAL para guardar el enum como un valor numérico en la base de datos, esto no es recomendable porque cualquier cambio en el orden de los valores en el enum afectará los datos en la base.
  • Validación y control de errores: Siempre es recomendable implementar validaciones y control de errores adecuados cuando se trabaja con enums en los controladores para asegurarse de que los valores proporcionados son válidos.

Conclusión

El uso de enum en las entidades de Spring Boot ayuda a crear un código más limpio y seguro, y facilita la gestión de valores constantes. La combinación de @Enumerated(EnumType.STRING) y un buen manejo de controladores y servicios permite trabajar con estos valores de manera eficiente y sin errores. Con este enfoque, tu aplicación será más robusta y menos propensa a fallos relacionados con valores inválidos.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer