Несколько возможных исходных свойств для целевого свойства «адрес»

#java #mapstruct

#java #mapstruct

Вопрос:

 @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) amp;amp; Objects.nonNull(dto.getAddress())) {
            return addressMapper.dtoToEntity(dto.getAddress());
        }
        if (Objects.nonNull(entity)) {
            return entity.getAddress();
        }
        return null;
    }
}
  

Я хочу сопоставить адрес даже из объекта dto, если dto равно нулю, я должен использовать информацию о сущности, я использовал этот пользовательский метод, но я получил и ошибку :

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

Ошибка понятна, ошибка возникает из-за того, что у объекта и dto есть атрибут address, но я не хочу устанавливать source , я хочу, чтобы он был вычтен из объекта или dto.

Есть ли какой-нибудь способ избежать этой ошибки, пожалуйста?

Ответ №1:

Я вижу несколько проблем в вашем решении.. Требуется ли вам цель сопоставления (как метод обновления?). Тогда вам нужен аргумент метода, подобный этому.(Обратите внимание, что я лично оставляю результат недействительным в этих случаях).

Затем: вам нужен только 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) amp;amp; Objects.nonNull(dto.getAddress())) {
            addressMapper.dtoToEntity(dto.getAddress());
        }
        if (Objects.nonNull(entity)) {
            entity.getAddress();
        }
    }
}

  

Комментарии:

1. Вы уверены, что ваш код компилируется? У вас есть метод void, и вы возвращаете null и другие