Es bueno que un marco como SpringBoot pueda hacer tantas cosas por ti.
Solo necesita una clase de entidad JPA más una interfaz de repositorio simple y SpringData le brinda todo lo que necesita para las operaciones típicas de bases de datos CRUD.
Escribes una clase de controlador REST simple y tienes una API REST ejecutándose, ¿verdad?
¡Oye, pero te olvidaste de escribir un DTO! Pero, ¿por qué lo necesitas cuando tu aplicación podría funcionar sin él?
Ciertamente hay algunas razones generales:
Pero también pueden suceder otras cosas extrañas. Te mostraré un ejemplo extraño basado en mi experiencia.
Este repositorio de GitHub contiene una aplicación sencilla que funciona sin los DTO. Hay una entidad de Usuario, cada Usuario puede tener múltiples Transacciones. Incluso tenemos un bean de servicio entre el repositorio y RestController, detectando posibles excepciones de acceso a la base de datos.
Como queremos crear una aplicación lista para producción, no queremos que Hibernate genere el DDL. En su lugar, tenemos un esquema.sql que crea las tablas (luego podemos cambiar a Flyway o Liquibase). Para nuestro ejemplo simple, también tenemos data.sql para que nuestras tablas no estén vacías.
Cuando ejecutamos la aplicación y llamamos al punto final API en http://localhost:8080/users, obtenemos el JSON esperado que contiene los usuarios y sus transacciones.
Ahora prestemos atención a las dos líneas de código en la clase Transacción, marcadas //!!
@JsonIgnore //!!
El primer olor es que en la clase Transacción tuvimos que agregar la anotación @JsonIgnore a la referencia de Usuario. Sin esa anotación, la serialización JSON falla debido a la recursividad infinita.
Ahora imaginemos que alguien comete un error al agregar otro campo (descripción) a la entidad Transacción, pero olvida ajustar las declaraciones SQL (o ejecuta la aplicación en un entorno donde no se ha aplicado el cambio de esquema).
descripción de cadena privada;//!!
Por supuesto, ahora la llamada a la API falla. ¡Pero mira el manejo de errores! La cláusula catch dentro de UserService no funciona como se esperaba. En lugar de eso, podemos ver un extraño seguimiento de pila en el registro:
GlobalExceptionHandler: Error inesperado org.springframework.http.converter.HttpMessageNotWritableException: No se pudo escribir JSON:
Una vez vi esta situación (claramente, con una aplicación mucho más grande que este ejemplo) y me tomó bastante tiempo entender por qué la excepción de SQL escapó del servicio y por qué recibía una excepción HttpMessageNotWritableException. ¿Puedes verlo?
Lo que sucede es que la clase UserService (a través del UserRepository) solo consulta la tabla de la base de datos USERS. Las entidades de transacción no son parte del resultado debido a la carga diferida predeterminada de Hibernate. Sólo cuando el deserializador Jackson intenta crear JSON desde la instancia de Usuario, invoca su método getTransactions que hace que Hibernate busque las entidades de Transacción.
Esta es la razón por la que obtenemos un seguimiento de pila extraño que combina elementos JSON y SQL. La excepción es detectada por GlobalExceptionHandler que no sabe qué hacer con ella, es por eso que el mensaje de registro es "Error inesperado".
Espero que este pequeño ejercicio te haga comprender más profundamente lo peligroso que es permitir que se mezclen diferentes capas de tu aplicación. Ver solo los escenarios de "día soleado" de su aplicación cuando aún es pequeña puede llevar a algunos desarrolladores a continuar haciendo lo incorrecto hasta que sea demasiado tarde.
No es necesario que escriba el código repetitivo que asigna los campos entre su DTO y las otras capas de su aplicación. MapStruct puede hacerlo por usted.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3