Over a million developers have joined DZone.

DataTransferObject Myth-Busting

· Java Zone

Discover how AppDynamics steps in to upgrade your performance game and prevent your enterprise from these top 10 Java performance problems, brought to you in partnership with AppDynamics.

DataTransferObject is one of the most popular design patterns. It has been widely used in archaic Java Enterprise application and some time ago got second live due to growth of RESTful APIs. I don't want to elaborate on DTOs pros (like for example hiding domain logic, etc) because there are whole books talking about it. I just want to cover technological aspects of DTO classes.

Usually we create just simple POJO with getters, setters and default constructor. The whole mapping configuration usually limits to @JsonIgnore annotation added on getter we want to skip.
It's the simplest way but can we do better? I'll focus on most popular in Java world Jackson Mapper and try to answer 3 basic questions which are usually skipped during development, and which in my opinion can improve the design of the transport layer.

1. Can we skip getters?

Yes! Jackson is able to serialize our objects using different strategies. Those strategies are fully customizable on two levels: for ObjectMapper and for particular object. If we for example want to serialize all fields for all pojos in our context notwithstanding presence of getter we can do something like this:

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)

To achieve the same result for single DTO you can use JsonAutoDetect annotation on class level:

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

Please notice that there are a lot different accessor settings - like including only public getters (and skipping package-protected), etc.

2. Are setters necessary?

No! Jackson can deserialize our objects without setters, and there is nothing special we have to do... except removing needless setters.

3. Is the default constructor required? I always add it due to "No suitable constructor found for type" exception.

No! Jackson comes with @JsonCreator annotations which can be used to specify given constructor to be used for deserialization.

public class Product {
    private final String name;
    public Product(@JsonProperty("name") String name) {
        this.name = name;
    public String getName() {
        return name;

This approach allows us to create immutable objects and use them for round-trip communication (serialize/deserialize). As you've probably noticed parameter name is redundant in this case. The good news is that since Java 8 it's possible to store parameter info in runtime. To do that we've to add -parameters option to javac compiler. Jackson have module activating such support. After including it in the project


and registering into ObjectMapper

objectMapper.registerModule(new ParameterNamesModule());

our brand new DTO looks as follows:

public class Product {
    private final String name;
    public Product(String name) {
        this.name = name;
    public String getName() {
        return name;

Note that @JsonCreator is needed only from jackson-databind 2.5.0. As you can see there are many options to make our DTOs lighter and prettier. The only thing needed is to understand how it's made :)

The Java Zone is brought to you in partnership with AppDynamics. AppDynamics helps you gain the fundamentals behind application performance, and implement best practices so you can proactively analyze and act on performance problems as they arise, and more specifically with your Java applications. Start a Free Trial.


Published at DZone with permission of Jakub Kubrynski, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}