2017-01-15 1 views
0

왜 두 번째 매핑 함수로 Mapstruct에 매핑 정보가 명확하게 주어지면 매핑 코드가 자동으로 생성되지 않습니까?mapstruct를 사용하여 구성된 객체에 평면 객체 매핑

Flat   Composed 
----   -------- 
- String a - String a 
       - Sub 
- String b  - String b 
- String c  - String c 

. 선명도

@Mapper(uses = SubToFlatMapper.class) 
public interface ComposedToFlatMapper { 

    Flat map(Composed c); // Unmapped target properties: "b, c". 
          // Not OK because Sub mapping is defined in 
          // SubToFlatMapper and is used here :(
} 

@Mapper 
public interface SubToFlatMapper { 

    Flat map(Sub s); // Unmapped target properties: "a". 
        // (OK because 'a' is not in Sub) 
} 

사용법 : 코드 생성이 그 방법을 생성하지 않기 때문에

Composed composed = new Composed(); 
Sub sub = new Sub(); 

composed.setA("A"); 
composed.setSub(sub); 

sub.setB("B"); 
sub.setC("C"); 

Flat flat = ComposedToFlatMapper.INSTANCE.map(composed); 

// flat.getA() is "A", OK! 
// flat.getB() is null, unexpected, should be "B" 
// flat.getC() also null, should be "C". 

"B""C"flat에 매핑되지 않습니다.

필자는 필요한 매핑 정보를 생성기에 제공했다고 생각했습니다. Flat map(Sub s) 메서드를 볼 때 내부에 ComposedToFlatMapperImpl이 생성되어야합니다.

편집는 :

내가 전에이 문제를 언급하지 않았지만, 원래의 질문에 나는 또한 더 유연 update -methods를 사용할 수 있습니다.

이제 새로운 Sub2 유형이 있다고 가정합니다. :

@Mapper(uses = {SubToFlatMapper.class, Sub2ToFlatMapper.class}) 
public interface ComposedToFlatMapper { 

    Flat map(Composed c); 

    void update(Composed source, @MappingTarget Flat target); 
} 

@Mapper 
public interface SubToFlatMapper { 

    Flat map(Sub s); 

    void update(Sub source, @MappingTarget Flat target); 
} 

@Mapper 
public interface Sub2ToFlatMapper { 

    Flat map(Sub2 s); 

    void update(Sub2 source, @MappingTarget Flat target); 
} 

. Flat 이후

Flat   Composed 
----   -------- 
- String a - String a 
       - Sub 
- String b  - String b 
- String c  - String c 
       - Sub2 
       - String d 
       - String e 

는 더 Sub2 참조 그냥 무시가 없습니다. 매핑 코드를 생성 할 필요가 없습니다.

+0

귀하의 매핑 방법은 대상으로 매개 변수와'Flat'로'Composed'있다; 그게 당신이 실제로 의미했던 것입니까, 아니면 다른 방향으로 있어야합니까 (매퍼 클래스 이름에 의해 암시 된 것처럼)? – Gunnar

+0

유스 케이스를 추가했습니다. – aliopi

+0

클래스 이름이 수정되었습니다. 나는 지금 그것을 읽는 것이 더 좋기를 바랍니다. – aliopi

답변

1

간단히과 같이 중첩 된 소스 구조를 평평하게 할 수 있습니다

@Mapper 
public interface ComposedToFlatMapper { 

    @Mapping(target="b", source="sub.b") 
    @Mapping(target="c", source="sub.c") 
    Flat map(Composed c); 
} 
+0

예,하지만 이는 중복 된 정보입니다. 생성기는'Sub' 타입에 대한 매핑을보고 그것을 사용해야합니다. 다른 말로하면'uses = '설정이 필요 없다는 것입니다. 이것은 너무 분명해서 나는 당신이 이것을 볼 수 없다고 생각하지 않는다. – aliopi

+0

Mapstruct가'Composed' 타입의 매핑을 시작하고'Sub' 타입을 보았을 때'SubToFlatMapper'에서'Flat map (Sub s)'메소드로/delegate를 사용해야합니다. 그렇지 않으면 강제로 Mapstruct의 작성 가능한 모델이 깨집니다. 하드 코딩 된 매핑을 지정합니다. 이 마지막 마일은 천재적 인 IMHO가됩니다. – aliopi

+0

그것이 작동하는 방식이 아니기 때문에 실제로 무엇을 제안 할 수 있는지 확신 할 수 없습니다. 'd'와'e'를 갖는'Sub2'와'Sub2ToFlatMapper'를 사용하는 또 다른 매퍼가 있다고 가정하십시오. 어떤 메소드'subToFlat()'또는'sub2ToFlat()'를 호출하여'FlatTo'의 인스턴스를 가져 와서'composToFlat()'에서 리턴해야합니까? – Gunnar