MapStruct no longer handles generic mapping methods (in conjunction with immutables) after upgrading from 1.4.x to version 1.5.x
Expected behavior
Given the following source and target models (immutable code generated by the immutables framework):
@Value.Immutable public interface ASource { ImmutableBSource getB(); } @Value.Immutable public interface ATarget { Optional<ImmutableBTarget> getB(); } @Value.Immutable public interface BSource { String getS(); } @Value.Immutable public interface BTarget { String getS(); }
and the following mapper definition:
public interface Mapper { ImmutableATarget map(ImmutableASource value); ImmutableBTarget map(ImmutableBSource value); default <T> Optional<T> wrapAsOptional(T value) { return Optional.ofNullable(value); } }
MapStruct 1.4.2 generated a correct mapper that uses the wrapOptional method for wrapping the b field in an optional after having converted it:
immutableATarget.b( wrapAsOptional( map( value.getB() ) ) );
Actual behavior
After upgrading to 1.5.3, MapStruct fails to generate a mapper and bails out with the following error message:
Can't map property "ImmutableBSource b" to "Optional<? extends com.bol.generics.ImmutableBTarget> b". Consider to declare/implement a mapping method: "Optional<? extends com.bol.generics.ImmutableBTarget> map(ImmutableBSource value)".I expect it to generate a mapping method similar to the one generated by version 1.4.x.
Steps to reproduce the problem
See https://github.com/ntinnemeier/mapstruct-1.5-upgrade-bugs/tree/main/generics-with-immutables for a full example.
Switch between version 1.4.x and 1.5.x to see the difference in behaviour.
I couldn't reproduce this behaviour with vanilla Java domain objects. That is to say, domain objects that are not generated by the immutables framework. I haven't checked what happens when the domain classes are generated by Lombok.
MapStruct Version
MapStruct 1.5.3