Skip to content

Mapping with "." (target this) can't find correct mapper #3475

@AndrisAncans

Description

@AndrisAncans

Expected behavior

Want to map inner object to current target.
Inner object mapping to current target defined in other mapper.

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = SubSourceToSubTargetMapper.class)
public interface SourceToTargetMapper {

    @Mapping(target = "subObject", source = ".")
    Target sourceToTargetMapper(SubSource source);

    @Mapping(target = ".", source = "subObject")
    SubSource targetToSubSource(Target target);

    @Mapping(target = "subObject", source = "subObject")
    Source targetToSource(Target target);
}

Expected all 3 mapping will use SubSourceToSubTargetMapper mapper.
Possible it is some workaround to use external method? Tried @Named in SubSourceToSubTargetMapper and adding qualifiedByName in @Mapping(target = ".", source = "subObject") didn't help. Single found solution is to duplicate mapping in targetToSubSource.

Actual behavior

Case with with target = "." targetToSubSource() ignores SubSourceToSubTargetMapper.

Generated Impl code:

@Component
public class SourceToTargetMapperImpl implements SourceToTargetMapper {

    @Autowired
    private SubSourceToSubTargetMapper subSourceToSubTargetMapper;

    @Override
    public Target sourceToTargetMapper(SubSource source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        target.setSubObject( subSourceToSubTargetMapper.sourceToTargetMapper( source ) );

        return target;
    }

    @Override
    public SubSource targetToSubSource(Target target) {
        if ( target == null ) {
            return null;
        }

        SubSource subSource = new SubSource();

        return subSource;
    }

    @Override
    public Source targetToSource(Target target) {
        if ( target == null ) {
            return null;
        }

        Source source = new Source();

        source.setSubObject( subSourceToSubTargetMapper.targetToSource( target.getSubObject() ) );
        source.setName( target.getName() );

        return source;
    }
}

Source targetToSource(Target target) found correct mapping method source.setSubObject() for same types pair.

Steps to reproduce the problem

Beans for mapping:

import lombok.Data;

@Data
public class Source {
    String name;
    String sourceSpecific;
    SubSource subObject;
}
import lombok.Data;

@Data
public class SubSource {
    String subSourceName;
}
import lombok.Data;

@Data
public class Target {
    String name;
    String targetSpecific;
    SubTarget subObject;
}
import lombok.Data;

@Data
public class SubTarget {
    String subTargetName;
}

Mappers:

import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingConstants;

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface SubSourceToSubTargetMapper {

    @Mapping(target = "subTargetName", source = "subSourceName")
    SubTarget sourceToTargetMapper(SubSource source);

    @InheritInverseConfiguration
    SubSource targetToSource(SubTarget target);
}
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingConstants;

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = SubSourceToSubTargetMapper.class)
public interface SourceToTargetMapper {

    @Mapping(target = "subObject", source = ".")
    Target sourceToTargetMapper(SubSource source);

    @Mapping(target = ".", source = "subObject")
    SubSource targetToSubSource(Target target);

    @Mapping(target = "subObject", source = "subObject")
    Source targetToSource(Target target);
}

MapStruct Version

1.5.5.Final

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions