MapStruct: ошибка возникает при использовании типа поля Target в качестве объекта - PullRequest
1 голос
/ 08 марта 2020

Когда я попытался для MapStruct преобразовать тип в Object, он не работал должным образом.

Целевой класс

public static class Filterable implements Name,Disassemble,Note{
    String name;
    String disassemble;
    Object note; // <-- Object type

    ... getter setter
}

Отображение абстрактного класса

@Mappings({
        @Mapping(source = "s",target = "name"),
        @Mapping(source = "s",target = "note"), // <--
        @Mapping(source = "s",target = "disassemble", qualifiedByName = "toDisassemble")
})
public abstract UiDto.Option.Filterable toUiFilterableOption(String s);

Результат при компиляции

@Override
public Filterable toUiFilterableOption(String s) {
    if ( s == null ) {
        return null;
    }

    Filterable filterable = new Filterable();

    filterable.setName( s );
    filterable.setNote( toUiFilterableOption( s ) ); // <-- hear is problem
    filterable.setDisassemble( Converter.toDisassemble( s ) );

    return filterable;
}

Как я мог решить эту проблему?

1 Ответ

1 голос
/ 08 марта 2020

MapStruct пытается найти метод, который сопоставляет исходный класс с целевым классом: Object map(String source).

Поскольку целевой класс равен Object, метод, помеченный @Mapping, сам имеет Подходящий метод подписи: Filterable toUiFilterableOption(String s). Потому что Filterable, как и любой другой класс в Java, является Object. И аргумент метода также является String.

. Чтобы решить эту проблему, используйте qualifiedByName в @Mapping и добавьте метод сопоставления, помеченный @Named:

@Mapper
public abstract class TestMapper {

  public static final TestMapper TEST_MAPPER = Mappers.getMapper(TestMapper.class);

  @Mapping(source = "s", target = "name")
  @Mapping(source = "s", target = "note", qualifiedByName = "toNote")
  @Mapping(source = "s", target = "disassemble", qualifiedByName = "toDisassemble")
  public abstract Filterable toUiFilterableOption(String s);

  @Named("toNote")
  protected Object toNote(String s) {
    return s.toUpperCase(); //just as an example
  }

  //...
}

. сгенерированный код выглядит так:

public class TestMapperImpl extends TestMapper {

  @Override
  public Filterable toUiFilterableOption(String s) {
    if (s == null) {
      return null;
    }

    Filterable filterable = new Filterable();

    filterable.setName(s);
    filterable.setNote(toNote(s));
    filterable.setDisassemble(toDisassemble(s));

    return filterable;
  }
}
...