2017-12-25 17 views
0

나는이 DTO 있습니다Mapstruct : DTO의 여러 필드를 Entity의 개체에 매핑하는 방법?

@Document(collection = "data") 
@EqualsAndHashCode 
public class DataDocument { 

    private static final long serialVersionUID = 1772572723546311500L; 

    @Id 
    private IdByDeviceIdAndGeneratedOn id; 

    public DataDocument() { 
    } 

    public IdByDeviceIdAndGeneratedOn getId() { 
     return id; 
    } 

    public void setId(IdByDeviceIdAndGeneratedOn id) { 
     this.id = id; 
    } 
} 

이가 MongoDB를 문서의 @Id 클래스입니다 : 이것은 매퍼가

@EqualsAndHashCode 
@ToString 
public class IdByDeviceIdAndGeneratedOn { 

    @Id 
    private final Long deviceId; 

    @Id 
    @Field("generated_on") 
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) 
    private final OffsetDateTime generatedOn; 

    public IdByDeviceIdAndGeneratedOn(final Long deviceId, final OffsetDateTime   generatedOn) { 
     this.deviceId = Objects.requireNonNull(deviceId); 
     this.generatedOn = Objects.requireNonNull(generatedOn); 
    } 

    public Long getDeviceId() { 
     return deviceId; 
    } 

    public OffsetDateTime getGeneratedOn() { 
     return generatedOn; 
    } 
} 

입니다

@NoArgsConstructor 
public class DataDTO implements DTO { 

    private static final long serialVersionUID = -5105904799152965475L; 

    private Long deviceId; 

    private OffsetDateTime generatedOn; 

    public Long getDeviceId() { 
     return deviceId; 
    } 

    public void setDeviceId(Long deviceId) { 
     this.deviceId = deviceId; 
    } 

    public OffsetDateTime getGeneratedOn() { 
     return generatedOn; 
    } 

    public void setGeneratedOn(OffsetDateTime generatedOn) { 
     this.generatedOn = generatedOn; 
    } 
} 

을 나는이 MongoDB의 문서가 이 Key 클래스 :

@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, componentModel = "spring") 
public interface IdByDeviceIdAndGeneratedOnMapper { 

    default IdByDeviceIdAndGeneratedOn toId(final Long deviceId, final OffsetDateTime generatedOn) { 
     return new IdByDeviceIdAndGeneratedOn(deviceId, generatedOn); 
    } 
    default Long getDeviceId(final IdByDeviceIdAndGeneratedOn id) { 
     return id.getDeviceId(); 
    } 

    default OffsetDateTime getGeneratedOn(final IdByDeviceIdAndGeneratedOn id) { 
     return id.getGeneratedOn(); 
    } 

이것은 DataDTO 및 DataDocument에 대한 @Mapper입니다 :

@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, 
    uses = {IdByDeviceIdAndGeneratedOnMapper.class, 
      AccelerometerDocumentMapper.class, 
      GpsDocumentMapper.class, 
      GsmDocumentMapper.class 
}) 
public interface DataDocumentMapper extends DocumentMapper<DataDTO, DataDocument> { 

} 

이 일반 매퍼입니다 : MongoDB의 데이터 docment에 대한 :

/** 
* Contract for a generic dto to entity mapper. 
* 
* @param <DTO> - DTO source type parameter. 
* @param <DOCUMENT> - MongoDB Document destination type parameter. 
*/ 

public interface DocumentMapper<DTO, DOCUMENT> { 

DOCUMENT toDocument(DTO dto); 

DTO toDto(DOCUMENT document); 

} 

현재 내가이 오류를 발생하고 있습니다

매핑되지 않은 대상 속성 : "id". DTO에 대한

:

매핑되지 않은 대상 속성 "의 DeviceID, generatedOn".

Id 클래스의 불변성을 잃지 않고이 오류를 해결하는 방법은 무엇입니까?

+0

수 당신도'DocumentMapper'를 공유합니까? – Filip

+0

@Filip added DocumentMapper – Igor

답변

0

내 문제가 해결되었지만이 부분이 멋지게 보입니다. 아마도 더 우아한 방법이 있을까요?

@Mapper(uses = {AccelerometerDocumentMapper.class, 
      GpsDocumentMapper.class, 
      GsmDocumentMapper.class}, 
imports = {IdByDeviceIdAndGeneratedOn.class}, 
componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) 
public interface DataDocumentMapper extends DocumentMapper<DataDTO, DataDocument> { 

@Override 
@Mapping(target = "id", expression = "java(new IdByDeviceIdAndGeneratedOn(dto.getDeviceId(), dto.getGeneratedOn()))") 
DataDocument toDocument(DataDTO dto); 

@Override 
@Mapping(target = "deviceId", expression = "java(document.getId().getDeviceId())") 
@Mapping(target = "generatedOn", expression = "java(document.getId().getGeneratedOn())") 
DataDTO toDto(DataDocument document); 
} 
0

(생성자를 사용하여 생성자를 사용하는 것)은 아직 지원되지 않습니다. 공개 문제는 #73입니다.

그러나 Object factories을 사용하여 찾고있는 것을 얻을 수 있습니다. toDocument 매핑의 경우 toDto 매핑의 경우 중첩 된 소스 매핑을 사용할 수 있습니다.

귀하의 매퍼과 같습니다

@Mapper(uses = {AccelerometerDocumentMapper.class, 
      GpsDocumentMapper.class, 
      GsmDocumentMapper.class}, 
componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR) 
public interface DataDocumentMapper extends DocumentMapper<DataDTO, DataDocument> { 

    @Mapping(target = "id", source = "dto") 
    @Override 
    DataDocument toDocument(DataDTO dto); 

    @ObjectFactory 
    default IdByDeviceIdAndGeneratedOn createId(DataDTO dto) { 
     return dto == null ? null : new IdByDeviceIdAndGeneratedOn(dto.getDeviceId(), dto.getGeneratedOn()); 
    } 


    @Mapping(target = "deviceId", source = "id.deviceId") 
    @Mapping(target = "generatedOn", source = "id.generatedOn") 
    @Override 
    DataDTO toDto(DataDocument document); 
} 

NB : 또한 DataDocumentMapper 추상 클래스를 만들 경우, createId 방법은 보호 할 당신이 인터페이스를 노출하지 않을 수