-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Open
Labels
Description
Expected behavior
Hello, we've had a problem in our project with unexpected mapstruct annotation behaviour, which lead to problems. We caught it early and updated our code and testing. However, initially we were led to believe things are working as expected. This is a sample of the code we had:
@Mapper(config = DefaultMapperConfig.class,
collectionMappingStrategy = CollectionMappingStrategy.ACCESSOR_ONLY
)
public abstract class GroupMapper {
@Mapping(target = "name", source = "name")
@Mapping(target = "parentGroupName", source = "parentGroup.name")
// other mappings...
public abstract GroupDto toDto(Group group);
@InheritConfiguration(source = "toDto")
@Mapping(target = "name", source = "groupNameDto.name")
public abstract GroupDto toDto(Group group, GroupNameDto groupNameDto);
}When trying to use this code this is what we expected:
- We can reuse the
toDtoconfiguration, because the full code has a lot of custom mappings, that we don't want to repeat. - We will add new methods using other dtos to do partial updates of our groups, as they are large and complex, and a single update is hard to maintain.
- The existing mappings will be reused from the
Group groupparameter, and anything that comes from theGroupNameDto groupNameDtocan be accessed using the full qualifier (so nothing will clash) - If this is not possible a compilation error will disallow this usage
Actual behavior
What actually happened:
- The mappings were inherited in an unexpected way
- Direct mappings e.g. from the Group to the Dto were fine
- More complex mappings e.g. accessing the parent Group (which is a different object of the same type nested inside the Group) were completely lost. Even when we tried modifying the original
toDtomethod with the full path e.g.group.parentGroup.namewe couldn't get it to work.
- In the documentation we couldn't find a specific mention of the intended behavior. But testing showed that things will work fine as long as there are no additional parameters. So for our case it wasn't possible to partially update our group with different dtos while reusing the original dto method.
- Our testing looked fine, because we didn't test ALL the fields for the new methods. Once it hit our testing environment we saw the inconsistencies and went back to the mapstruct implementation and saw its being generated wrong.
Our recommendation is to disallow compilation in the cases where @InheritConfiguration is used with incompatible parameters. Let me know your thoughts.
Steps to reproduce the problem
@MapperConfig(
componentModel = "spring",
collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE,
injectionStrategy = InjectionStrategy.CONSTRUCTOR,
builder = @Builder(disableBuilder = true),
subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION
)
public interface DefaultMapperConfig {
}MapStruct Version
1.6.3
ttulka