mapstruct目标对象设置了多次而不是更新

问题描述 投票:0回答:2

下面是我的映射器界面。我正在使用mapstruct 1.3.0.Final

@Mapper(componentModel = "spring")
public interface ApiMapper {
    @Mappings({
        @Mapping(source = "in.entityName.fn", target="name.fn"),
        @Mapping(source = "in.entityName.ln", target="name.ln"),
        @Mapping(source = "in.salute.sln", target="name.salutation"),
    })
    public MyOutput map(InputData in);
}

看起来超级简单,但是实现类在目标中两次设置了name对象,所以我只得到了最后一个映射对象。有人可以帮助我了解我在这里想念什么或做错什么吗?

@Component
public class ApiMapperImpl implements ApiMapper {

    @Override
    public MyOutput map(InputData in) {
        if ( in == null ) {
            return null;
        }

        MyOutput myOutput = new MyOutput();

        myOutput.setName( entityNameToNameDetails( in.getEntityName() ) );
        myOutput.setName( saluteServiceOutputToNameDetails( in.getSalute() ) );

        return myOutput;
    }

    protected NameDetails entityNameToNameDetails(EntityName entityName) {
        if ( entityName == null ) {
            return null;
        }

        NameDetails nameDetails = new NameDetails();

        nameDetails.setFn( entityName.getFn() );
        nameDetails.setLn( entityName.getLn() );

        return nameDetails;
    }

    protected NameDetails saluteServiceOutputToNameDetails(SaluteServiceOutput saluteServiceOutput) {
        if ( saluteServiceOutput == null ) {
            return null;
        }

        NameDetails nameDetails = new NameDetails();

        nameDetails.setSalutation( saluteServiceOutput.getSln() );

        return nameDetails;
    }
}
java mapping mapstruct
2个回答
0
投票

我认为,您应该在这种情况下帮助mapstruct,添加一个简单的方法,例如:

@Mappings({
    @Mapping(source = "in.entityName.fn", target="fn"),
    @Mapping(source = "in.entityName.ln", target="ln"),
    @Mapping(source = "in.salute.sln", target="salutation"),
})
public NameDetails mapNameDetails(InputData in);`

0
投票

我从herehere找到了答案。我喜欢第二个选项来使用@MappingTarget更新现有的bean。唯一的新变化是,我需要为MyOutput创建对象并在调用map方法时使用它。

我已经修改了我的映射器代码,如下所示:

@Mappings({
    @Mapping(source = "in.entityName.fn", target="out.name.fn"),
    @Mapping(source = "in.entityName.ln", target="out.name.ln"),
    @Mapping(source = "in.salute.sln", target="out.name.salutation"),
})
public void mapNameDetails(InputData in, @MappingTarget MyOutput out);

以上映射器代码的Junit

@Autowired
private ApiMapper apiMapper;

@Test
public void testApiMapper() {
 MyOutput output = new MyOutput();
 InputData input = createInputData();

 apiMapper.mapNameDetails(input, output);

 assertNotNull(output);
 assertNotNull(output.getName());

 assertEquals("Sridhar", output.getName().getFn());
 assertNull(output.getName().getLn());
 assertEquals("Mr.", output.getName().getSalutation());
}

private InputData createInputData() {
 InputData data = new InputData();

 data.setEntityName(new EntityName());
 data.setSalute(new SaluteServiceOutput());

 data.getEntityName().setFn("Sridhar");
 data.getSalute().setSln("Mr.");
 return data;
}
© www.soinside.com 2019 - 2024. All rights reserved.