目标属性“地址”的几种可能的源属性

问题描述

@Mapper(componentModel = "spring",injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class FooMapper {

    @Autowired
    static AddressMapper addressMapper;

    @Mapping(source = "entity.id",target = "id")
    @Mapping(target = "address",qualifiedByName = "mappingAddress")
    public abstract FooEntity dtoAndEntityToEntity(FooDto dto,FooEntity entity);
    
    @Named("mappingAddress")
    static AddressEntity mappingAddress(FooDto dto,FooEntity entity) {
        if (Objects.nonNull(dto) && Objects.nonNull(dto.getAddress())) {
            return addressMapper.dtoToEntity(dto.getAddress());
        }
        if (Objects.nonNull(entity)) {
            return entity.getAddress();
        }
        return null;
    }
}

我甚至想从dto实体映射地址,如果dto为null,我应该使用实体信息,我使用了该自定义方法,但是却出错了:

Error:(27,41) java: Several possible source properties for target property "address".

错误很明显,因为实体和dto具有地址属性,所以发生了错误,但是我不想设置source,我希望将其从实体或dto中扣除。

请问有什么方法可以避免此错误

解决方法

我在您的解决方案中看到了几个问题。您是否需要一个映射目标(作为更新方法?)。然后,您需要这样的方法参数。(请注意,在这种情况下,我个人将结果保留为空)。

然后:仅在遇到选择冲突时才需要qualifiedBy。因此,从本质上讲,如果您有多个具有相同签名的方法可供MapStruct选择。

最后,您需要指出它是您正在考虑的整个对象。


@Mapper(componentModel = "spring",injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class FooMapper {

    //@Autowired not sure whether you should use a static field for this,perhaps you should inject it at the place where you are going to use the mapper.
    // static AddressMapper addressMapper;

    @Mapping(source = "entity.id",target = "dto.id")
    @Mapping(target = "address",source = "dto" )
    public abstract void dtoAndEntityToEntity(FooDto dto,@MappingTarget FooEntity entity);
    

    // why was this method static? The mapper itself is already by design a singleton.
    @Named("mappingAddress")
    void mappingAddress(FooDto dto,@MappingTarget FooEntity entity) {
        if (Objects.nonNull(dto) && Objects.nonNull(dto.getAddress())) {
            addressMapper.dtoToEntity(dto.getAddress());
        }
        if (Objects.nonNull(entity)) {
            entity.getAddress();
        }
    }
}