Using MapStruct, I would like to map my RecipientDTO to Recipient. I want the AddressDTO from RecipientDTO to become the Address in every Subscription of Recipient.subscriptions. How do I achieve this with MapStruct? My classes look like this:
public class AddressDTO {
String street;
String city;
}
public class SubscriptionDTO {
String category;
}
public class RecipientDTO {
String name;
AddressDTO address;
List<SubscriptionDTO> subscriptions;
}
public class Address {
String street;
String city;
}
public class Subscription {
Address address;
String category;
}
public class Recipient {
String name;
List<Subscription> subscriptions;
}
I have tried specifying a separate mapper interface for Subscription. So
@Mapper
public interface SubscriptionMapper {
SubscriptionMapper INSTANCE = Mappers.getMapper(SubscriptionMapper.class);
@Mapping(target = "address", source = "addressDTO")
Subscription toSubscription(SubscriptionDTO dto, AddressDTO addressDTO);
}
This will generate a mapper for subscription.
But when I do
@Mapper(uses = SubscriptionMapper.class)
public interface RecipientMapper {
RecipientMapper INSTANCE = Mappers.getMapper(RecipientMapper.class);
Recipient toRecipient(RecipientDTO recipientDTO);
}
it will not use the mapping method with extra parameter from SubscriptionMapper.
I would like to do something like this if possible:
@Mapping(target = "subscriptions.address", source = "address")
Recipient toRecipient(RecipientDTO recipientDTO);
You need to use @AfterMapping annotation. This annotation allows you to add custom code after the standard mapping process.
@Mapper
public interface RecipientMapper {
RecipientMapper INSTANCE = Mappers.getMapper(RecipientMapper.class);
Recipient toRecipient(RecipientDTO recipientDTO);
@AfterMapping
default void updateAddresses(RecipientDTO recipientDTO, @MappingTarget Recipient recipient) {
if(Objects.nonNull(recipient) && !CollectionUtils.isEmpty(recipient.getSubscriptions())){
recipient.getSubscriptions().forEach(rcpt -> {
var address = recipientDTO.getAddress();
rcpt.setAddress(Address.builder().city(address.getCity()).street(address.getStreet()).build());
});
}
}
}