Cómo usar ObjectMapper para mapear entidades en un servicio reactivo con Spring WebFlux
Cuando trabajamos con aplicaciones reactivas en Spring WebFlux, muchas veces necesitamos transformar datos entre distintas capas de la aplicación. En este post, veremos cómo usar ObjectMapper
para mapear resultados de una base de datos a objetos de dominio en un entorno no bloqueante.
Contexto del código
Supongamos que tienes un servicio que obtiene configuraciones desde una base de datos reactiva, filtradas por un estado. Este es el método que implementamos:
testImplementation 'org.reactivecommons.utils:object-mapper:0.1.0'
implementation 'org.reactivecommons.utils:object-mapper:0.1.0'
Uso
private final ObjectMapper objectMapper;
@Override
public Flux<> getConfig(String state) {
return repository.findByState(state)
.map(res -> objectMapper.convertValue(res, ProcessConfig.class));
}
🔍 Desglosemos cada parte
1. private final ObjectMapper objectMapper;
ObjectMapper
es una clase de la biblioteca Jackson, muy usada para convertir objetos Java en JSON y viceversa. Sin embargo, también es útil para mapear entre diferentes clases Java (por ejemplo, de entidades a DTOs o clases de dominio).
Se declara como private final
para asegurar que:
- Privado: Solo la clase actual puede acceder al mapper.
- Final: No puede ser reasignado, lo cual es ideal para componentes inyectados.
💡 En una aplicación Spring Boot, normalmente se inyecta vía constructor para que esté gestionado por el contenedor de Spring.
2. repository.findByState(state)
Este método devuelve un Flux<Entidad>
, es decir, un flujo reactivo de elementos que cumplen con el filtro state
.
⚠️ Asumimos que res
es una entidad que viene directamente del repositorio, probablemente una entidad JPA o una clase específica de persistencia.
3. .map(res -> objectMapper.convertValue(res, ProcessConfig.class))
Aquí ocurre la magia. Cada resultado del Flux
es transformado (map
) a una nueva instancia de ReentryProcessConfig
.
Esto es útil si tu capa de persistencia devuelve una clase diferente a la que usas en la lógica de negocio. Por ejemplo:
ProcessConfigEntity
(persistencia) →ProcessConfig
(dominio)
🧠 ¿Por qué no usar directamente el constructor o un mapper manual?
- Simplicidad:
ObjectMapper
puede copiar todos los campos que coincidan en nombre y tipo, sin escribir código repetitivo. - Flexibilidad: Puedes aprovechar anotaciones como
@JsonIgnore
o@JsonProperty
. - Compatibilidad: Útil si ya usas Jackson en otros puntos del sistema.
🧼 Buenas prácticas
- ✅ Usa
ObjectMapper
solo cuando las clases sean similares y no haya lógica de transformación compleja. - ✅ Considera usar MapStruct o ModelMapper si necesitas mayor control o rendimiento.
- ✅ Asegúrate de no introducir errores silenciosos:
ObjectMapper
no lanza excepciones si faltan campos, lo cual puede ocultar bugs.
🎯 Conclusión
El uso de ObjectMapper
en servicios reactivas como Flux
permite transformar fácilmente entidades a objetos de dominio sin bloquear el flujo de datos. Es una herramienta poderosa que, usada con cuidado, puede hacer tu código más limpio y mantenible.