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).
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
.
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
}
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;
}
}
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> {
}
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);
}
}
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);
}
}
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.
enums
en los controladores para asegurarse de que los valores proporcionados son válidos.
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.
Jorge García
Fullstack developer