多个可能的源属性,用于目标属性“address”。

huangapple go评论67阅读模式
英文:

Several possible source properties for target property "address"

问题

@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;
    }
}

在不设置映射源属性(source)的情况下,您可以尝试以下方法来避免错误:

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

    @Autowired
    static AddressMapper addressMapper;

    @Mapping(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;
    }
}

以上代码中,@Mapping 注解中去除了 source 部分,这将允许 MapStruct 推断目标属性的来源,即使在 dto 和 entity 中都有相同的属性名。这样应该能够避免报错。

英文:
@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;
	}
}

I want to map the address even from entity of dto, if dto is null, I should to use entity info, I used that custom method, but I got and error :

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

The error is clear, the error happen because entity and dto have address attribute, but I don't want to set the source, I want it to be deducted from entity or dto.

Is there any way to avoid this error please?

答案1

得分: 1

以下是翻译好的内容:

我在您的解决方案中看到了几个问题。您是否需要一个映射目标(比如update方法)?那么您需要像这样的方法参数。(注意,在这些情况下,我个人会将结果设置为空)。

然后:只有在存在选择冲突时才需要使用qualifiedBy。因此,实质上,如果您有多个具有相同签名的方法供MapStruct选择。

最后,您需要指示您考虑的是整个对象。

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

    //@Autowired 不确定是否应该为此使用静态字段,也许您应该在将要使用映射器的地方注入它。
    // static AddressMapper addressMapper;

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

    // 为什么这个方法是静态的?映射器本身已经是一个设计上的单例。
    @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();
        }
    }
}
英文:

I see several issues in your solution.. Do you require a mapping target (as update method?). Then you need the method argument like that.( Note I personally leave the result void in those cases).

Then: you only need a qualifiedBy if you've got a selection conflict. So, in essence if you have multiple methods with the same signature for MapStruct to choose from.

Finally, you need to indicate that it's the whole object you are considering.


@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();
        }
    }
}

huangapple
  • 本文由 发表于 2020年9月1日 03:41:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63677177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定