Home Java javaTutorial What can happen if you skip the DTOs

What can happen if you skip the DTOs

Jul 30, 2024 am 09:46 AM

What can happen if you skip the DTOs

It is nice that a framework like SpringBoot can do so many things for you.

You just need a JPA entity class plus a simple repository interface and SpringData gives you all you need for typical CRUD database operations.

You write a simple REST controller class and you have a REST API running, right?

Hey, but you forgot to write a DTO! But why do you actually need it when your app could work without it?

There are certainly some general reasons:

  • layered structure (e.g. hexagonal architecture or ports and adapters): for maintainability it is a good idea to decouple the external communication code form the core (business logic)
  • security and performance: if you expose the database structure in your API as-is, you will soon get to a point where you expose more than needed; that can be misused by malicious actors or waste resources (CPU, memory and network bandwidth)
  • DTOs, unlike JPA entities, can be immutable (you can use Java records) and that is good for data-driven (functional) programming style, nice unit tests, safer concurrency etc.

But other strange things can happen, too. I will show you one weird example based on my experience.

This GitHub repo contains a simple application that works without the DTOs. There is a User entity, each User can have multiple Transactions. We even have a Service bean between the repository and the RestController, catching possible database access exceptions.

As we want to make a production-ready application, we do not want Hibernate to generate the DDL. Instead, we have a schema.sql that creates the tables (later we may switch to Flyway or Liquibase). For our simple example, we also have a data.sql so that our tables are not empty.

When we run the application and call the API endpoint at http://localhost:8080/users, we get the expected JSON containing the users and their transactions.

Now let's pay attention to the two lines of code in the Transaction class, marked //!!

@JsonIgnore //!!

The first smell is that in the Transaction class we had to add the @JsonIgnore annotation to the User reference. Without that annotation the JSON serialization crashes due to infinite recursion.

Now let's imagine that someone makes a mistake by adding another field (description) to the Transaction entity, but forgets to adjust the SQL statements (or runs the application against an environment where the schema change has not been applied).

private String description;//!!

Of course, now the API call fails. But look at the error handling! The catch clause inside the UserService does not work as expected. Instead we can see a strange stack trace in the log:
GlobalExceptionHandler : Unexpected error org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON:

I once saw this situation (clearly, with an application much larger than this example) and it took me quite a while to understand why the SQL exception escaped the service and why I was getting an HttpMessageNotWritableException. Can you see it?

What happens is, the UserService class (via the UserRepository) only queries the USERS database table. The Transaction entities are not part of the result because of the default Hibernate lazy loading. Only when the Jackson deserializer tries to create JSON from the User instance, it invokes its getTransactions method that makes Hibernate fetch the Transaction entities.

This is why we get a strange stacktrace combining JSON and SQL stuff. The exception is caught by the GlobalExceptionHandler that does not know what to do with it, this is why the log message is "Unexpected error".

I hope this little exercise will make you understand more deeply how dangerous it is to allow different layers of your application to mix. Seeing just the "sunny day" scenarios of your application while it is still small may lead some developers to continue doing the wrong thing until it is too late.

You do not have to write the boilerplate code mapping the fields between your DTO and the other layers of your application. MapStruct can do it for you.

The above is the detailed content of What can happen if you skip the DTOs. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1664
14
PHP Tutorial
1266
29
C# Tutorial
1239
24
Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Apr 19, 2025 pm 04:51 PM

Troubleshooting and solutions to the company's security software that causes some applications to not function properly. Many companies will deploy security software in order to ensure internal network security. ...

How do I convert names to numbers to implement sorting and maintain consistency in groups? How do I convert names to numbers to implement sorting and maintain consistency in groups? Apr 19, 2025 pm 11:30 PM

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

How to simplify field mapping issues in system docking using MapStruct? How to simplify field mapping issues in system docking using MapStruct? Apr 19, 2025 pm 06:21 PM

Field mapping processing in system docking often encounters a difficult problem when performing system docking: how to effectively map the interface fields of system A...

How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? Apr 19, 2025 pm 11:45 PM

Start Spring using IntelliJIDEAUltimate version...

How to safely convert Java objects to arrays? How to safely convert Java objects to arrays? Apr 19, 2025 pm 11:33 PM

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

How to elegantly obtain entity class variable names to build database query conditions? How to elegantly obtain entity class variable names to build database query conditions? Apr 19, 2025 pm 11:42 PM

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? Apr 19, 2025 pm 11:27 PM

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

How to use the Redis cache solution to efficiently realize the requirements of product ranking list? How to use the Redis cache solution to efficiently realize the requirements of product ranking list? Apr 19, 2025 pm 11:36 PM

How does the Redis caching solution realize the requirements of product ranking list? During the development process, we often need to deal with the requirements of rankings, such as displaying a...

See all articles