2-step mapping with generics does not work correctly.
Consider the following situation: (removed getter/setters to keep it short)
class Request { Nullable<ChildRequest> child; } class ChildRequest { String name; } class RequestDto { JsonNullable<ChildRequestDto> child; } class ChildRequestDto { String name; }
with the following mapper:
@Mapper public interface RequestMapper { RequestMapper INSTANCE = Mappers.getMapper( RequestMapper.class ); Request map(RequestDto dto); default <T> Nullable<T> jsonNullableToNullable(JsonNullable<T> jsonNullable) { if ( jsonNullable.isPresent() ) { return Nullable.of( jsonNullable.get() ); } return Nullable.undefined(); } default JsonNullable<ChildRequest> mapJsonNullableChildren(JsonNullable<ChildRequestDto> dtos) { if (dtos.isPresent()) { return JsonNullable.of( mapChild( dtos.get() ) ); } else { return JsonNullable.undefined(); } } ChildRequest mapChild(ChildRequestDto dto); }
This will not compile, but throw the following errors:
ERROR Issue2377Mapper.java:19 Nullable<ChildRequest> does not have an accessible constructor.
ERROR Issue2377Mapper.java:19 Can't map property "JsonNullable<ChildRequestDto> child" to "Nullable<ChildRequest> child". Consider to declare/implement a mapping method: "Nullable<ChildRequest> map(JsonNullable<ChildRequestDto> value)".
instead of generating the following code:
request.setChild( jsonNullableToNullable( mapJsonNullableChildren( dto.getChild() ) ) );
Discovered during analysis of #2377 .