Карта из нескольких источников DTO для одной цели - PullRequest
0 голосов
/ 05 ноября 2018

Использование MapStruct. Взять в качестве примера:

class Dto {
    DtoA a;
    DtoB b;
}

class DtoA {
    Long id;
    //...
}

class DtoB {
    Long id;
    //...
}


class Entity {
    AB ab;
}

Как мне сопоставить DtoA и DtoB с AB?

Я пытался:

public abstract Entity toEntity(Dto dto);

@Mappings({
            @Mapping(source = "a", target = "ab.a"),
            @Mapping(source = "b", target = "ab.b")
)}
public abstract AB toABEntity(DtoA a, DtoB b);

Хотя код сгенерирован *, метод toABEntity не вызывается.

* Плохо, так как сначала устанавливается a, но затем для установки b создается новый экземпляр ab, поэтому a теряется.

1 Ответ

0 голосов
/ 05 ноября 2018

Насколько я понимаю, вы хотите сопоставить Entity с Dto и объединить два поля Dto.a и Dto.b в одно поле Entity.ab.

Обычно, когда вы пытаетесь сделать это так:

@Mapper
public interface TestMapper {
    @Mappings({
        @Mapping(source = "a.id", target = "ab.aId", qualifiedByName = "toAB"),
        @Mapping(source = "b.id", target = "ab.bId", qualifiedByName = "toAB"),
    })
    Entity toEntity(Dto dto);
}

Сгенерированный маппер переопределяет экземпляр ab для каждого @Mapping, имеющего целевое свойство в ab. Это явно ошибка, и на MapStructs GitHub есть билет: https://github.com/mapstruct/mapstruct/issues/1148

Хотя есть обходной путь:

@Mapper
public interface TestMapper {
    @Mappings({
        @Mapping(source = "dto", target = "ab", qualifiedByName = "toAB"),
    })
    Entity toEntity(Dto dto);

    @Mappings({
        @Mapping(target = "aId", source = "a.id"),
        @Mapping(target = "bId", source = "b.id"),
    })
    AB toAB(Dto dto);
}

Я предположил, что класс AB равен:

class AB {
    public Long aId;
    public Long bId;
}

Сгенерированный код картографа:

public class TestMapperImpl implements TestMapper {

    @Override
    public Entity toEntity(Dto dto) {
        if ( dto == null ) {
            return null;
        }

        Entity entity = new Entity();

        entity.ab = toAB( dto );

        return entity;
    }

    @Override
    public AB toAB(Dto dto) {
        if ( dto == null ) {
            return null;
        }

        AB aB = new AB();

        Long id = dtoBId( dto );
        if ( id != null ) {
            aB.bId = id;
        }
        Long id1 = dtoAId( dto );
        if ( id1 != null ) {
            aB.aId = id1;
        }

        return aB;
    }

    private Long dtoBId(Dto dto) {
        if ( dto == null ) {
            return null;
        }
        DtoB b = dto.b;
        if ( b == null ) {
            return null;
        }
        Long id = b.id;
        if ( id == null ) {
            return null;
        }
        return id;
    }

    private Long dtoAId(Dto dto) {
        if ( dto == null ) {
            return null;
        }
        DtoA a = dto.a;
        if ( a == null ) {
            return null;
        }
        Long id = a.id;
        if ( id == null ) {
            return null;
        }
        return id;
    }
}
...