1

我有一个名为 TripEvent(持久性实体)的实体对象。请参阅下面我想提请注意的字段是 createdby 和列表​​ List

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

我的 DTO 类 Dep 是通过 Json 有效负载填充的宁静调用看起来像这样......

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 列表,以包含一个 createdby 字段,该字段不在 dto 上,但在列表中的所有实例上都是必需的。我通过将它们作为方法(接口)的参数传递来在顶层捏造了这一点。我不想提供自定义映射器来循环遍历列表并手动实例化和映射对象,因为映射正在工作100% 除了这个领域(s .. 我有更多)。

任何想法......我还应该提到 DTO 层不能更改,因为它来自另一个团队。

这是我在 ide 中遇到的错误的图像... error.png

4

1 回答 1

1

您可以做的是使用@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);
    }
}
于 2017-04-25T17:38:45.580 回答