Java – Can DTO contain additional helper methods

dtojava

I have a DTO like below

class OnlineProfileDTO {
  @JsonProperty("likes")
  SummaryDTO likes;

  // lots of other complex fields similar to above
}

class SummaryDTO {
  @JsonProperty("count")
  int count;
}

Now whenever I need likes count in a DTO to DBEntity converter, I need to check if onlineProfileDTO.getLikes() is null or not before calling onlineProfileDTO.getLikes().getCount(). Alternatively, catch NullPointerException and ignore it. But this will have to be done for all complex fields which can be potentially null.

Calling a common method like below can avoid the above repetition –

getCount(SummaryDTO anySummaryDTO) {
  if (anySummaryDTO != null) {
    return anySummaryDTO.getCount();
  }
  return 0;
}

Once above method is defined, one can use it to get Like count in following fashion:

getCount(onlineProfileDTO.getLikes())

My question is where should this method be ideally placed? More specifically, is it OK to move this method to DTO class which usually contains the transfer object fields along with their getters and setters only?

Approach 2:
One can also define getLikes() method in a way that it returns the count directly but its return datatype will be int.

Best Answer

This seems to me like an X/Y question. Your problem seems to really be with nulls here.

Try to avoid nulls as much as you can. As you have seen, they are a pain to work with.

For complex Sub-DTOs you can use the Null Object Pattern.

Also, you could let the (private) field be null and use java.util.Optional in the getter:

public Optional<Summary> getLikes() {
  return Optional.ofNullable(likes);
}

And then use it like this:

int count = onlineProfile.getLikes().map(Summary::count).orElse(0);

In this way you explicitly must define what happens when the value is not present, which is a good thing.

Finally, in simple cases you can use Jackson facilities to avoid ever having a null in your object, e.g. like this:

class OnlineProfileDTO {
  private int likes;

  @JsonCreator
  public OnlinceProfileDTO(
      @JsonProperty("likes") SummaryDTO likes,
      @JsonProperty("...") ...) {
    this.likes = likes == null ? 0 : likes.getCount();
  }
}
Related Topic