2017-02-01 5 views
3

私は、JPAエンティティをDTOにマップするためにMapstructを使い始めました。基本的なエンティティについては、これは素晴らしいです。同じソースクラスの拡張DTOをマップする方法

私の問題:一部のエンティティには、詳細を含む、遅延読み込みコレクションがあり、フェッチしてマップしたくない場合があります。解決策として、私はすべてのフィールドが常にマップされている基本スーパークラスと、コレクションを含むサブクラスを追加しました。どちらも同じエンティティを表しているため、同じソースクラスを使用します。

同じソースから両方の型にマップするメソッドを含むMapperを作成しようとすると、メソッドのシグネチャ(少なくとも戻り型)が異なっても、あいまいなマッピングメソッドのエラーが発生します。 これについて間違った方法はありますか?同じソースを使ってDTOのサブクラスを使用することはできませんか?

編集: それは重要な場合には、私はmapstruct-jdk8を使用しています:1.1.0.Final

編集2: 以下の例は、私の上に、一例に過ぎでした頭。私が実際にコードを使用したとき、それは機能しました。私の問題は、この例に含まれていなかったものであることが判明しました。チケットのコレクションをマッピングするメソッドを追加すると、エラーが発生するようです。おそらく、この問題は継承に(直接的に)関連していないことを意味します。私はおそらくいくつかの設定が欠けているだろうが、私は何を探すべきか分からない。

簡単な例:

チケットエンティティ

public class Ticket { 
    private long id; 
    private String title; 
    private Set<Comment> comments; 

    // Getters and setters 
} 

チケットDTOコメントDTOと

public class TicketDTO { 
    private long id; 
    private String title; 

    // Getters and setters 
} 

チケット

public class TicketWithCommentsDTO extends TicketDTO { 
    private List<CommentDTO> comments; 


    // Getters and setters 
} 

チケットマッパーインターフェース

@Mapper(uses= { CommentMapper.class }) 
public interface TicketMapper { 
    TicketDTO mapToTicketDTO(Ticket ticket); 

    List<TicketDTO> mapToTicketDTOList(Collection<Ticket> tickets); // Adding this method or the last method causes the error 

    TicketWithCommentsDTO mapToTicketWithCommentsDTO(Ticket ticket); 

    List<TicketWithCommentsDTO> MapToTicketWithCommentDTOList(Collection<Ticket> tickets); 
} 

コメントマッパーインターフェース

@Mapper 
public interface CommentMapper { 
    CommentDTO toCommentDTO(Comment comment); 

    List<CommentDTO> toCommentDTOList(Collection<Comment> comments); 
} 

エラーがスロー:

Ambiguous mapping methods found for mapping collection element to 
dto.TicketDTO: dto.TicketDTO mapToTicketDTO(model.Ticket ticket), 
dto.TicketWithCommentsDTO mapToTicketWithCommentsDTO(model.Ticket ticket). 
+0

あなたは多分私たちにあいまいな方法でエラーを投げているマッパーを表示することができますか?問題がどこにあるか(バグか何か他のもの)がより明確になるかもしれません – Filip

+0

@Filip、返信ありがとうございます!私は自分の質問を編集しました。どうぞご覧ください。あなたが何か他のものが必要な場合は教えてください。 – Steen

答えて

1

これは簡単な修正であることが判明しました。実際には構成上の問題がありませんでした。見つからなかったのは@IterableMapping注釈でした。

正しいタイプにelementTargetTypeを設定すると、すべて正常に機能します。

正しいマッパーコード

@Mapper(uses = { CommentMapper.class }) 
public interface TicketMapper { 
    TicketDTO mapToTicketDTO(Ticket ticket); 

    @IterableMapping(elementTargetType = TicketDTO.class) 
    List<TicketDTO> mapToTicketDTOList(Collection<Ticket> tickets); 

    TicketWithCommentsDTO mapToTicketWithCommentsDTO(Ticket ticket); 

    @IterableMapping(elementTargetType = TicketWithCommentsDTO.class) 
    List<TicketWithCommentsDTO> mapToTicketWithCommentDTOList(Collection<Ticket> tickets); 
} 
+0

あなたは答えを見つけたようです。私はちょうど1つの細部を明確にしたいと思う。 'elementTargetType'は' mapToTicketWithCommentDTOList'では必要ありません。その理由は、 'Ticket'を' TicketWithCommentsDTO'にマップできるメソッド上にしか存在しないからです(あなたの例が完成すれば)。反対に、 'Ticket'を' TicketDTO'( 'mapToTicketDTO'と' mapToTicketWithCommentsDTO')にマップできる2つのメソッドがあります。あいまいなエラーメッセージはここから来ます。 – Filip

+0

@Filipそれは理にかなっています(私はそれを捕まえなかったのは本当に恥ずかしいことです)。解明してくれてありがとう! – Steen

関連する問題