2017-02-01 2 views
3

Я начал использовать Mapstruct для привязки объектов JPA к DTO. Для базовых образов это отлично работает.Как перенаправить расширенные DTO из того же исходного класса

Моя проблема: некоторые объекты имеют ленивые загруженные коллекции, содержащие дополнительные данные, которые я не хочу всегда хотеть извлекать и отображать. В качестве решения я добавил базовый суперкласс со всеми полями, которые всегда отображаются, и подкласс, содержащий коллекции. Оба они представляют один и тот же объект, поэтому они используют один и тот же исходный класс.

Когда я пытаюсь создать Mapper, содержащий методы для сопоставления обоих типов из одного и того же источника, я получаю ошибку неоднозначных методов сопоставления, даже несмотря на то, что подпись метода (по крайней мере, тип возврата) отличается. Я об этом неправильно? Не могу ли я использовать подклассы для DTO, используя тот же источник?

Edit: В случае это особенно важно, я использую mapstruct-jdk8: 1.1.0.Final

Edit 2: В приведенном ниже примере просто пример, на вершине моего глава. Когда я действительно использовал код, он работал. Оказывается, моя проблема связана с чем-то, что не было включено в пример. Похоже, что ошибка возникает, когда я добавляю метод для сопоставления коллекции билетов. Вероятно, это означает, что проблема не связана (напрямую?) С наследованием. Вероятно, мне не хватает какой-либо конфигурации, но я не уверен, что искать.

Простой пример:

организация билетов

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

    // Getters and setters 
} 

билетов DTO

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

    // Getters and setters 
} 

билетов с комментариями DTO

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


    // Getters and setters 
} 

Mapper билетов интерфейс

@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

@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

@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

похоже, что вы нашли ответ. Я хотел бы прояснить одну небольшую деталь. Элемент 'elementTargetType' не нужен на' mapToTicketWithCommentDTOList'. Причина этого заключается в том, что существует только метод, который может отображать «Ticket» в «TicketWithCommentsDTO» (если ваши примеры завершены). С другой стороны, существует два возможных метода, которые могут отображать «Ticket» в «TicketDTO» («mapToTicketDTO» и «mapToTicketWithCommentsDTO»), здесь появляется неоднозначное сообщение об ошибке. – Filip

+0

@Filip Это имеет смысл (довольно смущающе, что я этого не поймал). Спасибо за разъяснения! – Steen

Смежные вопросы