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
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));
Another option would be
super((Class<List<MyEntity>>) (Class<?>) List.class,(Class<List<String>>) (Class<?>) List.class);
I very much inclined to @Ludovic solution, but there might be a catch as mentioned in my comment up there.
But a slight tweak works for me though - register the custom converter in "configuration" rather than field level. I'm using XML config but it should work with coding config:
<configuration>
<custom-converters>
<converter type="f.q.c.n.MyEntityToStringConverter">
<class-a>java.lang.String</class-a>
<class-b>f.q.c.n.MyEntity</class-b>
</converter>
</custom-converters>
</configuration>
来源:https://stackoverflow.com/questions/29033756/map-a-list-of-object-to-another-list-using-dozers-custom-converters