[英]Mapstruct mapping query :mapping an attribute from dto to entity but not an attibute on dto
I have a entity object called TripEvent (persistence entity) .. see below the field i would like to draw attention to is createdby and the list List 我有一个称为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;
.....
....
The TdfiFishGear class looks like the below snippet, again you can see a created by attribute. TdfiFishGear类看起来像下面的代码片段,再次您可以看到一个created by属性。
@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;
My DTO class Dep which is popluated via Json payload of a restful call looks like this... 我的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;
}
You can see if this DTO that there is no field called created by .. so on my mapping class you will see what i had to do, there are various calls to mappes which convert codes to ids etc etc 您可以查看是否该DTO没有由..创建的字段,因此在我的映射类上,您将看到我必须做的事情,有各种对mappe的调用,这些调用将代码转换为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);
....
...
So there are fields outside the dto object that are required in the entity objects, the mapping is working perfectly aside from these fields. 因此,实体对象中需要dto对象外部的字段,因此除了这些字段之外,映射还可以正常工作。
So i am trying to figure out how i can populate a list of tdfiFishgears from depDTo.gea to include a createdby field that is not on the dto but is required on all instances in the list. 因此,我试图弄清楚如何从depDTo.gea中填充tdfiFishgears列表,以包括一个不在dto上但列表中所有实例都必需的createdby字段。 I have fudged this at the top level by passing them in as parameters of the method(interface).. i dont want to have to provide a custom mapper to loop through the list and instantiate and mapp the objkects manually as, the mapping is working 100% apart from this field(s .. i have more of them).
我已经通过将它们作为method(interface)的参数传入来在顶级进行了欺骗。.我不想提供自定义映射器来遍历列表并手动实例化和映射objkect,因为映射正在工作除了这个领域的100%(S ..我有更多)。
Any ideas...i should also mention that the DTO layer cannot be changed as it is from another team. 任何想法...我还应该提到DTO层不能更改,因为它是来自另一个团队的。
Here is an image of the error i am getting in the ide... error.png 这是我在思想中遇到的错误的图像... error.png
What you can do is to use @AfterMapping
, @BeforeMapping
together with the latest 1.2.0 (not yet final, at the time of the post Beta2 is out) @Context
hooks so you can populate those fields. 您可以做的是将
@AfterMapping
, @BeforeMapping
与最新的1.2.0(在发布Beta2时尚未最终确定)一起使用@Context
挂钩,以便可以填充这些字段。
It will look something like: 它看起来像:
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());
}
}
If you don't want to have the @AfterMapping
in your interface, you can also include it in the Context object. 如果您不想在界面中使用
@AfterMapping
,也可以将其包含在Context对象中。
Like: 喜欢:
class ExtraFields {
private String createdBy;
public ExtraField(String createdBy) {
this.createdBy = createdBy;
}
@AfterMapping
public void afterFishGear(@MappingTarget fishGear) {
fishGear.setCreatedBy(createdBy);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.