Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map a collection with parameter with mapstruct

Tags:

java

mapstruct

To map a certain object with mapstruct I need some custom post processing which needs an additional parameter to do it's work:

@Mapper
public abstract class AlertConfigActionMapper {

    @Mappings({ @Mapping(target = "label", ignore = true)})
    public abstract AlertConfigActionTO map (AlertConfigAction action, Locale userLanguage);

    @AfterMapping
    public void setLabel (AlertConfigAction  action, @MappingTarget AlertConfigActionTO to, Locale userLanguage) {
        for (AlertConfigActionLabel label : action.getAlertConfigActionLabels()) {
            if (label.getLanguage().equals(userLanguage)) {
                to.setLabel(label.getLabel());
                break;
            } else if (label.getLanguage().equals(Locale.ENGLISH)) {
                to.setLabel(label.getLabel());
            }
        }

    }
}

This works just fine. The problem starts when I add following method to this mapper:

public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, Locale userLanguage);

I need to pass this parameter (userLanguage) as well but mapstruct seems to 'break down' in this case: I generates following code for this part (which naturally gives a compilation error):

@Override
public List<AlertConfigActionTO> mapList(List<AlertConfigAction> actions, Locale userLanguage) {
    if ( actions == null && userLanguage == null ) {
        return null;
    }

    List<AlertConfigActionTO> list = new List<AlertConfigActionTO>();

    return list;
}

I'm sure it is related to the parameter since if I remove it (from all mapping methods) then the mapList method is generated correctly.

What is needed to be done to allow custom parameters in this case?

like image 490
Stijn Geukens Avatar asked Apr 04 '16 10:04

Stijn Geukens


People also ask

How do you map a list of objects using MapStruct?

Using Mapstruct we can map list in similar fashion as we map primitives. To get a list of objects, we should provide a mapper method which can map an object.

What is MapStruct used for?

MapStruct is a code generator tool that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is fast, type-safe, and easy to understand.

Does MapStruct use reflection?

During compilation, MapStruct will generate an implementation of this interface. This implementation uses plain Java method invocations for mapping between source and target objects, i.e. no reflection or similar.

How do you ignore property in MapStruct?

We can ignore unmapped properties in several mappers by setting the unmappedTargetPolicy via @MapperConfig to share a setting across several mappers. We should note that this is a simple example showing the minimal usage of @MapperConfig, which might not seem much better than setting the policy on each mapper.


1 Answers

What you describe is not possible (yet). Could you open a feature request in our issue tracker? We should provide means of denoting parameters as some sort of "context" which is passed down the call stack.

As a work-around for the time being, you might take a look at using a ThreadLocal which you set before invoking the mapping routine and which you access in your after-mapping customization. It's not elegant - and you need to make sure to clean up the thread local to avoid memory leaks - but it should do the trick.

like image 54
Gunnar Avatar answered Sep 18 '22 18:09

Gunnar