Spring Entities should convert to Dto in service?

We are talking about software architecture and as always when we are talking about software architecture there are a thousand ways of doing something and many opinions about what is the best way. But there is no best way, everything has advantages and disadvantages. Keep this in mind!

Typically you have different layers:

  • A persistence layer to store data
  • Business layer to operate on data
  • A presentation layer to expose data

Typically, each layer would use its own kind of objects:

  • Persistence Layer: Repositories, Entities
  • Business Layer: Services, Domain Objects
  • Presentation Layer: Controllers, DTOs

This means each layer would only work with its own objects and never ever pass them to another layer.

Why? Because you want each layer to be separated from the other layers. If you would use entities in your controller, your presentation would depend on how your data is stored. That’s really bad. Your view has nothing to do with how the data is stored. It shouldn’t even know that or how data is stored.

Think of that: You change your database model, e.g. you add a new column to one of your database tables. If you pass the entities to your controller (or worse: your controller exposes them as JSON), a change at the database would result in a change in your presentation. If the entities are directly exposed as JSON, this might even result in changes in JavaScript or some other clients which are using the JSON. So a simple change in the database might require a change in the JavaScript front end, because you couple your layers very tight. You definitely don’t want that in a real project.

How? You doubt that this is practical, so just a small example of how to do that in (pseudo) code:

class Repository {
    public Person loadById(Long id) {
        PersonEntity entity = loadEntityById(id);
        Person person = new Person();
        person.setId(entity.getId());
        person.setName(entity.getFirstName + " " + entity.getLastName());
        return person;
    }
}

In this example, your repository would use entities internally. No other layer knows or uses this entities! They are an implementation detail of this particular layer. So if the repository is asked to return a “person”, it works on the entity, but it will return a domain object. So the domain layer which works with the repo is save in the case the entities need to be changed. And as you can see in the case of the name, the domain and the database might be different. While the database stores the name in first name and last name, the domain only know a single name. It’s a detail of the persistence how it stores the name.

The same goes for controllers and DTOs, just another layer.

Leave a Comment