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

1

There are 1 answers

0
Filip On BEST ANSWER

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.