2017-04-25 39 views
0

我有一個名爲TripEvent(持久性實體)的實體對象..請參閱下面我想引起注意的字段被創建和列表 列表結構映射查詢:從屬性映射到實體,但不是一個屬性在dto

@Entity 
@Table(name = "TRIPEVENT") 
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@tripeventId") 
public class Tripevent implements Serializable { 

... 
... 

@Id 
@SequenceGenerator(name = OracleConstants.TRIPEVENT_TRIPEVENTID_GENERATOR, sequenceName = OracleConstants.TRANSACTIONSEQUENCE_NAME, allocationSize = OracleConstants.TRANSACTIONSEQUENCE_ALLOCATION_SIZE) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = OracleConstants.TRIPEVENT_TRIPEVENTID_GENERATOR) 
@Column(unique = true, nullable = false, precision = 10) 
private long tripeventid; 


@Column(precision = 10) 
private Long activitytypeid; 

@Column(nullable = false, length = 1) 
private String alertind; 

@Column(nullable = false, length = 1) 
private String completedind; 

@Column(nullable = false) 
private Timestamp createdate; 

@Column(nullable = false, length = 20) 
private String createdby; 
.... 
.... 
@OneToMany(mappedBy = "tripevent", cascade = CascadeType.PERSIST) 
@JsonManagedReference(value = "tripevent-fishgear") 
    private List<TdfiFishgear> tdfiFishgears; 
..... 
.... 

TdfiFishGear類看起來像下面的代碼片段,您可以再次看到創建的屬性。

@Entity 
@Table(name = "TDFI_FISHGEAR") 
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@fishgearId") 
public class TdfiFishgear implements Serializable { 
private static final long serialVersionUID = 1L; 


@Id 
@SequenceGenerator(name = OracleConstants.TDFI_FISHGEAR_TDFIFISHGEARID_GENERATOR, sequenceName = OracleConstants.TRANSACTIONSEQUENCE_NAME, allocationSize = OracleConstants.TRANSACTIONSEQUENCE_ALLOCATION_SIZE) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = OracleConstants.TDFI_FISHGEAR_TDFIFISHGEARID_GENERATOR) 
@Column(name = "TDFI_FISHGEARID", unique = true, nullable = false, precision = 10) 
private long tdfiFishgearid; 


@Column(precision = 8) 
private Long avghookcount; 


@Column(precision = 15, scale = 3) 
private BigDecimal avgnetheight; 


@Column(precision = 10) 
private Long avgnetheighuomid; 


@Column(precision = 15, scale = 3) 
private BigDecimal avgnetlength; 


@Column(precision = 10) 
private Long avgnetlengthuomid; 


@Column(nullable = false) 
private Timestamp createdate; 


@Column(nullable = false, length = 20) 
private String createdby; 


@Column(precision = 6, scale = 1) 
private BigDecimal fishingdepth; 


@Column(nullable = false, precision = 10) 
private Long geartypeid; 


@Column(nullable = false, length = 1) 
private String inactiveind; 


private Timestamp lastchangedate; 

其通過寧靜通話的Json有效載荷popluated我的DTO類德普看起來像這樣...

public class Dep { 

    public Dep(){ 
    } 

    @NotEmpty(message = "seqNo: is a required field") 
    @JsonProperty("seqNo") 
    private String seqNo = null; 


    @NotNull(message = "depTStamp: is a required field") 
    @JsonProperty("depTStamp") 
    private ZonedDateTime depTStamp = null; 


    @NotEmpty(message = "port: is a required field") 
    @JsonProperty("port") 
    private String port = null; 


    @JsonProperty("nonEUPort") 
    private String nonEUPort = null; 


    @NotEmpty(message = "activity: is a required field") 
    @JsonProperty("activity") 
    private String activity = null; 


    @JsonProperty("comments") 
    private String comments = null; 


    @JsonProperty("spe") 
    @Valid 
    private List<DepSpe> spe = new ArrayList<DepSpe>(); 


    @JsonProperty("gea") 
    @Valid 
    private List<NonFarGea> gea = new ArrayList<NonFarGea>(); 


    public Dep seqNo(String seqNo) { 
    this.seqNo = seqNo; 
    return this; 
    } 

你可以看到,如果這DTO沒有名爲領域所創造..所以在我的映射類,你會看到什麼我不得不這樣做,有哪個轉換代碼IDS等等等等

@Mapper(componentModel="spring", 
uses = { 
ZonedDateTimeStampMapper.class, 
ConfigMapperFromCode.class, 
RasDepMapper.class 
}, 
unmappedTargetPolicy = ReportingPolicy.IGNORE 
) 


public interface DepToTripEventMapperApi { 


/*root mapper from a dep dto to a entity trip event*/ 

@Mappings(
    { 
    @Mapping(target = "createdby", source = "regUserId"), 
    @Mapping(target = "createdate",expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"), 
    @Mapping(target = "inactiveind", constant = "N"), 
    @Mapping(target = "eventtypeid", qualifiedByName={"ConfigMapperFromCode", "returnDepEventId"}), 
    @Mapping(target = "activitytypeid", qualifiedByName={"ConfigMapperFromCode", "activityIdFromCode"}, source="depDto.activity"), 
    @Mapping(target = "marineportid", qualifiedByName={"ConfigMapperFromCode", "portIdFromCode"}, source = "depDto.port"), 
    @Mapping(target = "alertind", constant = "N"), 
    @Mapping(target = "eventnote", source = "depDto.nonEUPort"), 
    @Mapping(target = "ersseqno", source = "depDto.seqNo"), 
    @Mapping(target = "skippercomment", source = "depDto.comments"), 
    @Mapping(target = "tdfiErsmessageid", source = "messageId"), 
    @Mapping(target = "startdate", source = "depDto.depTStamp"), 
    @Mapping(target = "completedind", constant = "N"), 
    @Mapping(target = "vessel", source = "vessell"), 
    @Mapping(target = "triplogs", source = "tripLogs"), 
    @Mapping(target = "lastchangedate", ignore = true), 
    @Mapping(target = "lastchangedby", ignore = true), 
    @Mapping(target = "tdfiCatchmovements", ignore = true), 
    @Mapping(target = "tdfiFishgears", source="depDto.gea"), 
    .. 
    } 
) 
Tripevent DepDtoToTripEvent(Dep depDto, String regUserId, Long messageId, Vessel vessell, List<Triplog>tripLogs); 



// mapper from nonnfargea to fishing gear 
@Mappings(
{ 
@Mapping(target = "meshdimension", source = "gea.gearDims"), 
@Mapping(target = "geartypeid", qualifiedByName={"ConfigMapperFromCode", "gearIdFromCode"}, source = "gea.gearType"), 
@Mapping(target = "avgnetheight", source = "gea.avNetHeight"), 
@Mapping(target = "avgnetlength", source = "gea.avNetLength"), 
@Mapping(target = "meshsize", source = "gea.meshSize"), 
@Mapping(target = "avghookcount", source = "gea.avHooks"), 
@Mapping(target = "totnetquantity", source = "gea.noNets"), 
@Mapping(target = "tothookscount", source = "gea.totHooks"), 
@Mapping(target = "totnetlength", source = "gea.totLen"), 
@Mapping(target = "trawltypeid", qualifiedByName={"ConfigMapperFromCode", "speciesIdFromCode"}, source = "gea.trawlType") 
} 
) 
TdfiFishgear geaToFishGear(NonFarGea gea); 

.... 
... 

所以有所需的DTO的對象之外領域mappes各種調用實體對象,除了這些字段外,映射完全可以工作。

所以我想弄清楚如何從depDTo.gea填充tdfiFishgears的列表,以包含不在dto上但是在列表中的所有實例上都需要的createdby字段。我已經通過將它們作爲方法(接口)的參數傳遞給頂層來欺騙它。我不想提供自定義映射器來循環訪問列表,並手動實例化和映射objkects,因爲映射工作正常從這個領域100%(s ..我有更多的)。

任何想法......我還應該提到DTO層不能改變,因爲它來自另一個團隊。

這裏是我在IDE中發現了錯誤的圖像... error.png

回答

0

你可以做的是使用@AfterMapping,用最新的1.2.0(尚未最終@BeforeMapping一起,在當時的帖子Beta2已發佈)@Context掛鉤,以便您可以填充這些字段。

它看起來是這樣的:

class ExtraFields { 

    private String createdBy; 
    //Getters omitted 
} 

public interface DepToTripEventMapperApi { 

    //Your mappings 
    Tripevent DepDtoToTripEvent(Dep depDto, String regUserId, Long messageId, Vessel vessell, List<Triplog>tripLogs, @Context ExtraFields extra); 

    //Your mappings 
    TdfiFishgear geaToFishGear(NonFarGea gea, @Context ExtraFields extra); 

    @AfterMapping 
    default void afterMapping(@MappingTarget TdfiFishgear fea, @Context ExtraFields extra) { 
     fea.setCreatedBy(extra.getCreatedBy()); 
    } 
} 

如果你不希望有@AfterMapping在你的界面,你也可以將其包含在上下文對象。

像:

class ExtraFields { 

    private String createdBy; 

    public ExtraField(String createdBy) { 
     this.createdBy = createdBy; 
    } 

    @AfterMapping 
    public void afterFishGear(@MappingTarget fishGear) { 
     fishGear.setCreatedBy(createdBy); 
    } 
} 
+0

感謝我是這個變化之後得到一個編譯錯誤的答覆......在跳機事件映射器不再承認geaToFishGear映射器時,我的@Context參數添加到它的接口.. 。無法將屬性「java.util.List gea」映射到「java.util.List tdfiFishgears「。考慮聲明/實現映射方法:「java.util.List map(java.util.List 值)「。它是tdfiFishGears的列表。 – Fordey

+0

您需要將'@ Context'添加到所有使用'geaToFishGear'映射器的映射器,而不僅僅是映射器本身。他們是否在同一個映射器或不同的映射器?您是否已將'@ Context'添加到'DepDtoToTripEvent'? – Filip

+0

嗨..我添加到所有映射器(2),有2個映射器,一個映射旅行事件對象(其中包含齒輪列表)和一個將齒輪實例映射到列表中的映射器... – Fordey