Search code examples
javamapstruct

Mapstruct: How to use custom mappers with @MappingTarget


I am using Mapstruct and I need to update an existing bean using @MappingTarget, but need to apply some complex logic to set the correct field in the target.

Lets say I have a target bean that looks like this. A user has a list of accounts, and one of those accounts is marked as favourite.

UserDetails {
  String name;
  List<Account> accounts;
}

Account {
  String id;
  boolean favourite;
}

The DTO class contains the account ID of their favourite account.

UserDetialsDTO {
  String name;
  String favouriteAccountId;
  List<String> accountIds;
}

I need to use some complex logic to update the correct Account in the list of accounts.

UserDetails fromDto(UserDetialsDTO dto, @MappingTarget UserDetails userDetails);

The logic of finding and updating the correct Account to make it favourite is something like this:

userDetails.accounts
           .stream()
           .forEach(acct -> acct.setFavourite(dto.favouriteAccountId.equals(acct.id))) ;

How can I tell Mapstruct to use this custom logic when updating a @MapingTarget?


Solution

  • try:

        @Mapper 
        public interface MyMapper {
    
             @Mapping( target = "accounts", ignore = true ) 
             void fromDto(UserDetialsDTO dto, @MappingTarget UserDetails userDetails);
    
             @AfterMapping
             default void handleAccounts(UserDetialsDTO dto, @MappingTarget UserDetails userDetails) {
                 userDetails.accounts
                   .stream()
                   .forEach(acct -> acct.setFavourite(dto.favouriteAccountId.equals(acct.id))) ;
             }
        }