Mapstruct映射查询:将属性从dto映射到实体但不是dto

时间:2017-04-25 16:21:54

标签: java entity-framework mapstruct

我有一个名为TripEvent(持久性实体)的实体对象..请参阅下面的字段我想提请注意创建者和列表 列表

@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有效负载弹出的我的DTO类Dep看起来像这样......

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是否没有被称为创建的字段..所以在我的映射类中你会看到我必须做的事情,有各种调用mappes将代码转换为id等等

@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对象外部的字段,除了这些字段外,映射工作正常。

所以我想弄清楚如何从depDTo.gea填充tdfiFishgears列表,以包含不在dto上但在列表中的所有实例上都需要的createdby字段。我通过将它们作为方法(接口)的参数传递给顶级的fudged ..我不想要提供一个自定义映射器来循环遍历列表并手动实例化和mapp objkects,映射工作正常距离这个领域100%(s ..我有更多的)。

任何想法......我还应该提到DTO图层不能像其他团队那样被更改。

以下是我在ide ... error.png

中遇到的错误的图片

1 个答案:

答案 0 :(得分:0)

你可以做的是使用@AfterMapping@BeforeMapping和最新的1.2.0(在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,也可以将其包含在Context对象中。

像:

class ExtraFields {

    private String createdBy;

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

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