After thinking about it for a while, I decided that the best approach is to validate on both layers. I'll explain why.
Imagine that you have a User
entity with a name
field and your application business logic requires it not to be null. You also have a UserDTO
with the same name
field.
I assume that all your validations on both, entity and DTO, will be made using the java.validation
API.
If you validate only on the controller, then you're safe against persisting an invalid entity, but only from a incoming request. If you have a service that manipulates the entity, it may persist the entity in an invalid state without you noticing (unless there is a null check on the database column).
Then, you can think: "OK, I'll move the validation annotations from the DTO to the entity and all will be fine". Well, yes and no!
If you validate only on the entity, you will be safe from both, incoming requests and on your service layer, however you may have a performance problem.
According to Anghel Leonard on its book Spring Boot Persistence Best Practices, every time you load an entity from the database, Hibernate wastes memory and CPU to maintain the entity state on the persistence context, even if the entity is in "read only mode".
Now, think about it. If the user name is null and you validate it only on the entity, this means that you:
- Started a transaction
- Loaded the entity
- Changed the entity
- Flushed the persistence context
- Rolled back the transaction
Many of these operations can be expensive and you did it all just to throw it on the trash, when you could simply have never done anything if you had validated the user name earlier.
So, my advice is to validate on both layers. The annotations make it so easy that you not even have an excuse to not do it. Even complex validations can be made writing custom validators, which can then be reused on a lot of other places
Also, here is a link to the book I mentioned, I hope you enjoy:
https://www.amazon.com.br/dp/B087WS81RK/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1