I recently picked up MapStruct, and I really like the way it works. Since I'm new to MapStruct, I apologize in advance if this question is silly or makes little sense.
Due to server version, I'm bound to Java 6.
I have 3 types of entities, A, B, and C, as well as their DTO counterparts.
public class A{
//...
}
public class B extends A{
//...
}
public class C extends A{
//...
}
public class ADto{
//...
}
public class BDto extends ADto{
//...
}
public class CDto extends ADto{
//...
}
My mapper defines:
public abstract ADto mapAToADto(A source);
public abstract A mapADtoToA(ADto source);
public abstract BDto mapBToBDto(B source);
public abstract B mapBDtoToB(BDto source);
public abstract CDto mapCToCDto(C source);
public abstract C mapCDtoToC(CDto source);
Which works fine for now.
In my application, I work with List<A>
and List<ADto>
that contains both subtypes.
My current implementation was to implement my own mapping method that iterates over source list and checks types with instanceof
, then calls matching mapping method listed above.
Current implementation:
public <T extends ADto, S extends A> List<T> toList(List<S> source) {
if (source == null) {
return null;
}
List<T> list = new ArrayList<T>();
for (S entity : source) {
if (entity instanceof B) {
list.add((T) mapBToBDto((B) entity));
} else if (entity instanceof C) {
list.add((T) mapCToCDto((C) entity));
} else {
list.add((T) mapADtoToA((A) entity));
}
}
return list;
};
I was wondering if there is a way to direct MapStruct to figure it out automatically. Am I missing something?
Edit: My optimistic approach was with:
@IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL)
public abstract <T extends ADto, S extends A> List<T> listAToADto(List<S> source);
Which results in:
Can't generate mapping method for a generic type variable target
Thank you
MapStruct is a code generator tool that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is fast, type-safe, and easy to understand.
In general, mapping collections with MapStruct works in the same way as for simple types. Basically, we have to create a simple interface or abstract class and declare the mapping methods. Based on our declarations, MapStruct will generate the mapping code automatically.
Using Mapstruct we can map list in similar fashion as we map primitives. To get a list of objects, we should provide a mapper method which can map an object.
During compilation, MapStruct will generate an implementation of this interface. This implementation uses plain Java method invocations for mapping between source and target objects, i.e. no reflection or similar.
Your implementation is correct. MapStruct is an Annotation Processor that generates code during compilation. We don't generate any reflection checks (All the types that implement and interface or extend a class are not known during compilation). Therefore your approach to the problem is correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With