Search code examples
javaspringarraylistormdozer

Map a list of object to another list using Dozer's custom converters


What I am trying to do is to map a List of entities to a list of their String ids (more or less) using Dozer.

Obviously, it implies Custom Converter. My first idea was to make a converter from MyEntity to a String, and then say to Dozer something like "Map every object of this collection using this converter". But I couldn't figure out how to do so.

So my second idea was to make a converter form a list of entities to a list of string, directly. My problem on this idea is that I was strugling on something ridiculous which is to get the type of my list in the constructor, as below (which doesn't work at all):

public MyEntityListConverter() {
    super(List<MyEntity>.class, List<String>.class);
}

I don't know how to pass an instantiated list's class in a single row wihout declaring anything.

So if someone know either :

  • How to specify to dozer an object convertor to use in collection mapping
  • How to get instantiated list type
  • A third/better solution to try

Solution

  • The way you tried is not possible due to generic types. And if it was, Dozer cannot detect types at runtime.

    1st solution with List<>

    Your converter :

    public class MyEntityToStringConverter extends DozerConverter<MyEntity, String> {
        // TODO constructor + impl
    }
    

    Your mapping :

    mapping(MyEntityA.class, MyEntityB.class)
    .fields("myEntityList", "myStringList",
        hintA(MyEntity.class),
        hintB(String.class));
    
    mapping(MyEntity.class, String.class)
    .fields(this_(), this_(), customConverter(MyEntityToStringConverter.class));
    

    2nd solution with list wrappers

    You can try to create your custom classes extending a list impl.

    public class MyEntityList extends ArrayList<MyEntity> {
    
    }
    
    public class MyStringList extends ArrayList<String> {
    
    }
    

    Change your field in the parent classes you want to map.

    Your converter :

    public class MyEntityToStringConverter extends DozerConverter<MyEntityList, MyStringList> {
        // TODO constructor + impl
    }
    

    Your mapping :

    mapping(MyEntityA.class, MyEntityB.class)
    .fields("myEntityList", "myStringList", customConverter(MyEntityToStringConverter.class));