I'm trying to make a mapping using MapStruct but I don't know how to deal with the fields from one to the other. I have the classes below:
class DataDomain {
private List<Domain> data;
}
class Domain {
private String codDist;
private String numFun;
private String txtJust;
private Boolean valPar;
private LocalDateTime dateHr;
private Integer numPn;
}
class DataEntity {
private String codDist;
private String numFun;
private List<ParEntity> pares;
}
class ParEntity {
private String numFun;
private String txtJus;
private String indValPar;
private String dateHr;
private String numPn;
}
interface ParOutMapper{
ParOutMapper INSTANCE = Mappers.getMapper(ParOutMapper.class);
@Mapping(target = "data", source = "entity")
DataDomain map(DataEntity entity);
Domain toDomain(DataEntity entity);
default List<Domain> toList(DataEntity entity) {
return entity != null ? singletonList(toDomain(entity)) : new ArrayList<>();
}
default DataEntity map(DataDomain domain) {
return domain != null
&& domain.getData() != null
&& !domain.getData().isEmpty() ? toEntity(domain.getData().get(0)) : null;
}
DataEntity toEntity(Domain domains);
List<Domain> toDomainList(List<DataEntity> domainList);
}
That's what I've done so far, but it's giving divergence in the mapping because both have different structures and I ended up getting lost in how to apply their origin and destination field to field. If possible and someone knows how to do it in an interesting correct way I would be very grateful.
CodePudding user response:
I would suggest the following solution
@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR,
componentModel = "spring",
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
builder = @Builder(disableBuilder = true))
public interface ParOutMapper {
@Mapping(target = "data", source = "entity")
DataDomain map(DataEntity entity);
@Mapping(target = "txtJust", source = "pares", qualifiedByName = "txtJust")
@Mapping(target = "valPar", source = "pares", qualifiedByName = "valPar")
@Mapping(target = "dateHr", source = "pares", qualifiedByName = "dateHr")
@Mapping(target = "numPn", source = "pares", qualifiedByName = "numPn")
Domain toDomain(DataEntity entity);
default List<Domain> toList(DataEntity entity) {
return entity != null ? singletonList(toDomain(entity)) : new ArrayList<>();
}
default DataEntity map(DataDomain domain) {
return domain != null
&& domain.getData() != null
&& !domain.getData().isEmpty() ? toEntity(domain.getData().get(0)) : null;
}
@Mapping(target = "pares", ignore = true)
DataEntity toEntity(Domain domains);
List<Domain> toDomainList(List<DataEntity> domainList);
@AfterMapping
default DataEntity valuesToList(Domain domains, @MappingTarget DataEntity dataEntity){
ParEntity parEntity = new ParEntity();
parEntity.setDateHr(domains.getDateHr().toString()); // alternative call custom entity to list mapping here !
parEntity.setTxtJus(domains.getTxtJust());
parEntity.setNumPn(domains.getNumPn().toString());
parEntity.setNumFun(domains.getNumFun());
parEntity.setIndValPar(domains.getValPar().toString());
dataEntity.setPares(List.of(parEntity));
return dataEntity;
}
@Named("txtJust")
default String mapTxtJust(List<ParEntity> pares) {
return pares.get(0).getTxtJus(); // or custom mapping logic here
}
@Named("valPar")
default Boolean mapValPar(List<ParEntity> pares) {
return Boolean.valueOf(pares.get(0).getIndValPar()); // or custom mapping logic here
}
@Named("dateHr")
default LocalDateTime mapDateHr(List<ParEntity> pares) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
return LocalDateTime.parse(pares.get(0).getDateHr(),formatter); // or custom mapping logic here
}
@Named("numPn")
default Integer mapNumPn(List<ParEntity> pares) {
return Integer.valueOf(pares.get(0).getNumPn()); // or custom mapping logic here
}
}
- Since you tagged your question with spring-boot i assume you are using it. Therefore i would suggest to use the provided component model by mapstruct in its configuration
- I am unsure how you want to do your mapping of list to entitiy or entity to list. With my approach you can do it value by value or with the entire list. Both workes either way.
- The solution compiles and workes for
DataEntity toEntity(Domain domains);
andDomain toDomain(DataEntity entity);
i did not recognize any other problems since mapstruct is able to generate the required mappings.