# Migrando a Spring Boot 3: Un Viaje a la Modernización (y sus Desafíos)

Si eres un desarrollador de Spring Boot, sabes que mantenerte actualizado es clave. La llegada de Spring Boot 3 trae consigo un cambio importante y necesario: la transición de [`java.util.Date`](http://java.util.Date) a la API de tiempo de Java (`java.time.*`). Aunque este cambio es fundamental para la modernización y la seguridad de nuestras aplicaciones, no es un simple reemplazo de un tipo de dato por otro.

Recientemente me enfrenté a este proceso y quiero compartir los puntos clave que debes considerar para que tu migración sea lo más fluida posible.

#### 1\. Adiós a [`java.util.Date`](http://java.util.Date), Hola a `LocalDate`

El primer y más evidente cambio es dejar atrás `Date`. Si bien [`java.util.Date`](http://java.util.Date) funcionaba, era una clase con problemas conocidos de mutabilidad y manejo de zonas horarias. La nueva API `java.time` ofrece tipos específicos para cada necesidad:

* `LocalDate`: Para fechas (`2023-11-03`).
    
* `LocalTime`: Para horas (`15:30:00`).
    
* `LocalDateTime`: Para fecha y hora (`2023-11-03T15:30:00`).
    

El reto aquí no es solo cambiar el tipo en tu código, sino también la forma en que los datos se manejan en el backend y el frontend.

#### 2\. La Serialización: Del Timestamp al Array

Aquí es donde surge la principal fricción con las aplicaciones existentes. Por defecto, cuando Jackson (la biblioteca de serialización de Spring) encuentra un campo [`java.util.Date`](http://java.util.Date), lo convierte a un **timestamp** (un número largo). Sin embargo, con `LocalDate`, el comportamiento por defecto es serializarlo como un **array JSON** (`[2023, 11, 3]`).

Si tu frontend espera un timestamp, esto causará errores. La solución es configurar la serialización de Jackson en el backend para que `LocalDate` se convierta a un timestamp. Esto se puede lograr fácilmente con la anotación `@JsonFormat` directamente en el campo de tu entidad:

```java
import com.fasterxml.jackson.annotation.JsonFormat;
// ...
@JsonFormat(shape = JsonFormat.Shape.NUMBER_INT)
private LocalDate fechaDePublicacion;
```

#### 3\. Actualizaciones en la Configuración de JPA y Hibernate

La validación de esquemas en Spring Boot 3 es mucho más estricta. Ya no puedes confiar en que Hibernate "adivine" el tipo de dato correcto. Si tienes columnas con tipos específicos, ahora debes definirlas explícitamente:

* **Decimales**: Olvídate de `@Column(columnDefinition = "decimal", precision = 10, scale = 2)`. Ahora debes usar el formato estándar de SQL: `@Column(columnDefinition = "DECIMAL(10, 2)")`.
    
* **Tipos de Columna**: Si usabas `@Type` para especificar el tipo de una columna, ahora la mejor práctica es usar la anotación `@Column` directamente.
    

#### 4\. Cambios en el Manejo de Fechas en el Código

Al migrar tu lógica de negocio, tus métodos que antes usaban `Date` ahora deben ser reescritos para usar `LocalDate`. Por ejemplo, para sumar días, el método `plusDays()` de `LocalDate` es mucho más claro y sencillo que la manipulación de milisegundos que se hacía con `Date`.

**Antes:**

```java
public static Date generateFixedDate(Date dateWithOffset, int offset) {
    long epochMilli = dateWithOffset.toInstant().toEpochMilli() + ...;
    return new Date(epochMilli);
}
```

**Ahora**

```java
public static LocalDate generateFixedDate(LocalDate dateWithOffset, int offset) {
    return dateWithOffset.plusDays(offset);
}
```

Cuando migras una aplicación de Spring Boot 2 a 3, uno de los desafíos más grandes es lidiar con los cambios en las dependencias y la configuración. Aquí está el ítem número 5 para tu blog, enfocado en cómo manejar el cambio de `javax` a `jakarta`.

---

## 5\. El gran cambio de `javax` a `jakarta`: Tu nueva lista de tareas

Si hay una única tarea que debes priorizar al migrar a Spring Boot 3, es la de **actualizar tus paquetes de** `javax` a `jakarta`. Este cambio no es una simple cuestión de estilo; es una modificación fundamental en la API de Java EE (ahora conocida como Jakarta EE). El equipo de Spring Boot adoptó por completo el nuevo ecosistema, y tus proyectos deben hacer lo mismo. Ignorar este paso resultará en errores de compilación y de tiempo de ejecución.

### ¿Qué paquetes son los más afectados?

* **JPA (Java Persistence API):** Si tu aplicación usa Hibernate, la mayoría de tus entidades, como `@Entity`, `@Table`, y `@Id`, deben cambiar su importación de `javax.persistence` a `jakarta.persistence`. Sin esta actualización, tu `EntityManagerFactory` no se inicializará y el proyecto no se ejecutará.
    
* **Servlets:** Las clases relacionadas con el manejo de peticiones web, como `HttpServletRequest` y `HttpServletResponse`, deben cambiar de `javax.servlet` a `jakarta.servlet`.
    
* **Validación:** Las anotaciones de validación como `@Valid` o `@Size` también migran de `javax.validation` a `jakarta.validation`.
    
* **JAXB y JTA:** Los paquetes para la serialización de XML y la gestión de transacciones distribuidas (`javax.xml.bind` y `javax.transaction`) también se mueven a `jakarta.xml.bind` y `jakarta.transaction`, respectivamente.
    

### ¿Cómo hacerlo de forma eficiente?

En lugar de ir archivo por archivo, utiliza las herramientas de tu IDE. La mayoría de los entornos de desarrollo como **IntelliJ IDEA** tienen una función de búsqueda y reemplazo a nivel de proyecto. Simplemente busca `javax.` y reemplázalo por `jakarta.`. Ten cuidado de no reemplazar los paquetes que no migraron, como `javax.crypto` que es parte del JDK estándar.

Al hacer este cambio, estarás alineado con la última versión de la plataforma Java, lo que te permitirá aprovechar las nuevas características y mejoras de rendimiento de Spring Boot 3 y sus dependencias.

### Conclusión

La migración a Spring Boot 3 es un paso inevitable hacia adelante. Aunque la transición de `Date` a `LocalDate` presenta desafíos en la serialización y validación, la inversión de tiempo vale la pena. Ganas en claridad del código, seguridad de tipos y te alineas con los estándares modernos de Java.

Es un proceso que requiere paciencia y atención a los detalles, pero al final, tu aplicación será más robusta y fácil de mantener.
