Issue
I am trying to use MapStruct for a structure similar to the following:
Source:
public class ClassSource{
private int id;
private String name;
private String numT;
private List<CustAddress> addresses = null;
private Person person;
}
public class CustAddress implements Serializable {
@JsonProperty("postalCode")
private String postalCode;
}
public class Person implements Serializable {
@JsonProperty("jobTitle")
private String jobTitle;
}
Destination :
public class ClassDestination {
private int id;
private String name;
private String numT;
private List<CustAddress> addresses = null;
}
public class CustAddress implements Serializable {
@JsonProperty("zipCode")
private String zipCode;
}
public class Person implements Serializable {
@JsonProperty("workTitle")
private String workTitle;
}
want to achieve the below mapping from Address list postalcode to destination address list zipcode and Person jobTitle on the subclass to target Person workTitle
public interface PersonMapper {
@Mapping(source = "addresses.postalCode", target = "addresses.zipCode")
@Mapping(source = "person.jobTitle", target = "person.workTitle")
ClassDestination map(ClassSource source);
The above @mapping not referring the subclass properly from source to destination.. it's throwing exceptions
Solution
@Getter
@Setter
@Builder
static class ClassSource {
private int id;
private String name;
private String numT;
private List<AddressSource> addresses;
private PersonSource person;
}
@Getter
@Setter
@Builder
static class AddressSource implements Serializable {
@JsonProperty("postalCode")
private String postalCode;
}
@Getter
@Setter
@Builder
static class PersonSource implements Serializable {
@JsonProperty("jobTitle")
private String jobTitle;
}
@Getter
@Setter
@Builder
@ToString
static class ClassDestination {
private int id;
private String name;
private String numT;
private List<AddressDestination> addresses;
private PersonDestination person;
}
@Getter
@Setter
@Builder
@ToString
static class AddressDestination implements Serializable {
@JsonProperty("zipCode")
private String zipCode;
}
@Getter
@Setter
@Builder
@ToString
static class PersonDestination implements Serializable {
@JsonProperty("workTitle")
private String workTitle;
}
@Mapper(uses = {AddressMapper.class})
interface ClassMapper {
@Mapping(source = "person.jobTitle", target = "person.workTitle")
ClassDestination sourceToDestination(ClassSource source);
}
@Mapper
interface AddressMapper {
@Mapping(source = "postalCode", target = "zipCode")
AddressDestination sourceToDestination(AddressSource source);
}
private static final ClassMapper classMapper = Mappers.getMapper(ClassMapper.class);
public static void main(String[] args) {
PersonSource personSource = PersonSource.builder().jobTitle("Dev").build();
List<AddressSource> addressSources =
List.of(
AddressSource.builder().postalCode("412101").build(),
AddressSource.builder().postalCode("411001").build());
ClassSource classSource =
ClassSource.builder()
.id(1)
.name("Firstname")
.numT("2")
.addresses(addressSources)
.person(personSource)
.build();
ClassDestination classDestination = classMapper.sourceToDestination(classSource);
System.out.println(classDestination);
}
I created a temp scenario locally. I have used an additional mapper for mapping nested objects. This should work.
Answered By - Keshavram Kuduwa
Answer Checked By - Pedro (JavaFixing Volunteer)