Migrando a Spring Boot 3: Un Viaje a la Modernización (y sus Desafíos)
I have worked as a frontend and backend developer handling technologies such as Django, Ionic, Laravel, MySQL, Spring (Java), Oracle, NodeJS, Angular, VueJS with the goal of developing websites and mobile applications that offer high performance and are interactive.
You can learn more about me by visiting my website: www.stalinmaza.com
#frontend #backend #fullstack #javascript #nodejs #php
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 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, Hola a LocalDate
El primer y más evidente cambio es dejar atrás Date. Si bien 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, 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:
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
@Typepara especificar el tipo de una columna, ahora la mejor práctica es usar la anotación@Columndirectamente.
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:
public static Date generateFixedDate(Date dateWithOffset, int offset) {
long epochMilli = dateWithOffset.toInstant().toEpochMilli() + ...;
return new Date(epochMilli);
}
Ahora
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 dejavax.persistenceajakarta.persistence. Sin esta actualización, tuEntityManagerFactoryno se inicializará y el proyecto no se ejecutará.Servlets: Las clases relacionadas con el manejo de peticiones web, como
HttpServletRequestyHttpServletResponse, deben cambiar dejavax.servletajakarta.servlet.Validación: Las anotaciones de validación como
@Valido@Sizetambién migran dejavax.validationajakarta.validation.JAXB y JTA: Los paquetes para la serialización de XML y la gestión de transacciones distribuidas (
javax.xml.bindyjavax.transaction) también se mueven ajakarta.xml.bindyjakarta.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.

