2017-01-15 20 views
0

マッピング情報がMapstructに第2のマッピング関数によって明示的に与えられている場合、これが自動的にマッピングコードを生成しないのはなぜですか?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(Subs) 'メソッドに/ delegateを使用しなければなりません。そうでなければ、Mapstructの作成可能なモデルは、私はハードコーディングされたマッピングを指定します。この最後のマイルは天才IMHOになります。 – aliopi

+0

それはそれがどのように機能しているかではなく、私はあなたが実際に働くことが示唆されるものがよく分からない。 'd'と' e'を持つ 'Sub2'と' Sub2ToFlatMapper'を使った別のマッパーがあるとします。 'StoToFlat() 'または' sub2ToFlat() 'のどのメソッドを呼び出すと、' 'FlatTo''のインスタンスを取得して' 'composToFlat()'から返すべきですか? – Gunnar

関連する問題