Be a Developer, not a Blender

Let us Return to the DTOs World

I am not here to say if the correct term is DTO, but I am here to say that we must use it.

In the first page of this post I said that is not a good practice to mix frameworks concepts. Let us see again a code snippet from the first page:

@Entity
@XmlRootElement
@JsonAutoDetect
@DiscriminatorColumn(name = "animal_type")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
        @JsonSubTypes.Type(value = Bird.class, name = "bird")
})
public class Animal {
 
    @Id
    private int id;
 
    @JsonSerialize(using = JsonDateSerializer.class)
    private Date birthday;
 
    @JsonView(ToothView.class)
    @OneToMany(mappedBy = "animal")
    private List<Tooth> teethList;
 
    // other stuff
}

In the code above we have JPA and JSON mixed in the same class. The problem with this approach is that every update in the JPA code could affect the returned JSON for the VIEW; every update in the JSON could affect the way that the Entity is persisted in the database.

When I talked about VIEW I am not talking about HTML, but I am talking about every request response in the project. By saying request response I mean: HTML, WebServices, REST (JSON, XML), SOAP, files, etc.

We need to keep the VIEW code decoupled from the MODEL code. An easy way to achieve this is using the DTO pattern.

DTO means Data Transfer Object that is the term that defines a class that will only carry data. A DTO class will not have business rules or any code that will execute some action, it only holds data.

Below we can see a code that is using DTO:

public DogDTO getDogById(int id){
    final Dog dog = dogRepository.findById(id);
 
    final DogDTO dogDTO = new DogDTO();
    dogDTO.setId(dog.getId());
    dogDTO.setName(dog.getName());
 
    return dogDTO;
}

In the code above the entity is protected from the VIEW and all annotation the JSON annotation will/must be put inside the DTO class. If you need to add an attribute to the Dog entity the VIEW will not be affected, the DTO will remain the same.

The problem in the DTO approach is that if your DTO class has 25 attribute you will need to invoke 25 setters to populate the data. But to this “problem” there is an easy way to do it.

How can I easily pass the Entity data to a DTO?

There are frameworks that help passing the data from one class to another. I will talk about two frameworks that has a class with the same name BeanUtils: Apache and Spring.

Take a look at the code below:

BeanUtils.copyProperties(source, target);

Using the Apache or Spring library we can copy the data from one class to another without any problem. Each library has its approach and requirements, it is a good idea to study each one before deciding which one is the best for your project.

Conclusion

Do not return your JPA entity to the VIEW. Do not couple your business layer to the data visualization layer.

2 thoughts on “Be a Developer, not a Blender

Leave a Comment