Convert List to another List with multiple parameters

Viewed 6619

I have an existing mapping of 2 objects ExpertJpa to ExpertDto that need another param to filter ExpertJpa. This map working properly and now I try to convert List of ExpertJpa to List of ExpertDto, I add this second param.

@Mappings({
        @Mapping(target = "status", ignore = true),
        @Mapping(target = "profile", source = "input.expertProfile"),
        @Mapping(target = "engagementId", expression = "java(new MapperHelper().ReturnExpertEngagementIdByApiKey(input,identity))"),
        @Mapping(target = "campaignId", expression = "java(new MapperHelper().ReturnExpertCampaignIdByApiKey(input,identity))"),

})
Expert ExpertJpaToExpert(com.consumer.expert.dbaccessor.entities.Expert input, Identity identity);

List<Expert> ListExpertsJpaToListExperts(List<com.consumer.expert.dbaccessor.entities.Expert> input, Identity identity);

On build, I get Error message that List is an interface and cannot be instance....

Error:(53, 18) java: The return type java.util.List is an abstract class or interface. Provide a non abstract / non interface result type or a factory method.

1 Answers

MapStruct can do this automatically for you. However it cannot handle multiple argument methods (in principle it maps source to target).

Having said that, if you rewrite your code a little bit it you could get rid of the expression and have a full type safe solution.

So:

class IdentityContext {

   private final Identity id;
   private final MapperHelper mapperHelper; 

   public IdentityContext(Identity id){
       this.id = id;
       this.mapperHelper = new MapperHelper();
   }

   @AfterMapping
   public void setIds(com.consumer.expert.dbaccessor.entities.Expert input, @MappingTarget Expert expertOut) {
      expertOut.setEngagementId( mapperHelper.ReturnExpertEngagementIdByApiKey(input,identity) );
      expertOut.setCampaignId( mapperHelper. ReturnExpertCampaignIdByApiKey(input,identity) );

   }
} 

now define your mapper as such:

@Mappings({
        @Mapping(target = "status", ignore = true),
        @Mapping(target = "profile", source = "input.expertProfile")        
})
Expert ExpertJpaToExpert(com.consumer.expert.dbaccessor.entities.Expert input, @Context IdentityContext ctx);

List<Expert> ListExpertsJpaToListExperts(List<com.consumer.expert.dbaccessor.entities.Expert> input, @Context IdentityContext ctx)

Note: MapStruct will now recognise the list mapping because the IdentityContext is marked as @Context (so: it will be only set in the calling method but in essence not be part of the mapping source-target itself).

Related