mapstruct / mapstruct/mapstruct
Mapping with "." (target this) can't find correct mapper
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 7.7k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the supplied SourceToTargetMapper and SubSourceToSubTargetMapper reproducer, then inspect the generated SourceToTargetMapperImpl for handling of target="." and the uses mapper. Compare that path with the working source.setSubObject() mapping; done means targetToSubSource delegates the inner-object mapping to SubSourceToSubTargetMapper rather than returning an empty SubSource.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100