2017-12-25 7 views
0

私はこのDTOを持っている:Mapstruct:複数のフィールドをDTOからEntityのオブジェクトにマップする方法は?

@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のドキュメントを持っている:

@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; 
    } 
} 

これがためにマッパーでありますこの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が追加されました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方法が保護作るあなたがインターフェイスでそれを公開したくないことができ

関連する問題