DTO to domain converter with Java 8 and CDI


DTO is often the thing we don’t want to do but it is actually quite important to get them to be able to make the application evolving without breaking everything each time.

The main difficulties is you often need a unitary convert method from DTO to domain and another one for lists, maybe one for map…and this for each resource you have. Using inheritance for it works but then you have a technical inheritance which then prevent you to get real inheritance in Java.

That’s why it is nice to use something else.

With CDI it was possible to add a custom bean doing the boilerplate (unitary -> list for instance) for you but it mandates to change the API: if you converter is MyDtoToDomainConverter then you’ll get an ObjectConverter or something close.

With Java 8 this is no more needed. Just create an interface which maps a DTO to a domain object. From a signature point of view it can be a Function since it will get the method:

DTO apply(DOMAIN t);

Then just extends Function<A> (or redefine this method to get a better semantic) and add a default method mapping a list of DTOs to a Stream of DOMAINs and finally converting the obtained Stream to a list of DOMAINs:

public interface SuperConverter<A, B> extends Function<A, B> {
    default List<B> convertToList(final List<A> input) {
        return input.stream().map(this::apply).collect(toList());
    }
}

An simple implementation could look like:

public class PersonDtoToPersonConverter implements SuperConverter<PersonDto, Person> {
    @Override
    public Person apply(final PersonDto input) {
        final Person person = new Person();
        person.setAge(input.getAge());
        person.setName(input.getName());
        return person;
    }
}

You can even go further if you accept to be linked to a framework like ModelMapper. In this last case the base method used by all default ones will be the mapper (object from the framework).

Finally just get this method injected in any CDI object/EJB and use it:

@Singleton
@Startup
public class Tester {
    @Inject
    private PersonDtoToPersonConverter converter;

    public List<Person> testConverters(final List<PersonDto> dtos) {
        return converter.convertList(dtos);
    }
}

This kind of converter is really nice with JAXRS. Of course you can map.collect for each method when needed but making it shorter is really better and more efficient.

Want more content ? Keep up-to-date on my new blog

Or stay in touch on twitter @rmannibucau

2 thoughts on “DTO to domain converter with Java 8 and CDI

Leave a comment