Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mapStruct: map list to other list?

Tags:

mapstruct

I have a list List<Payment> which I'd like to map to another list List<PaymentPlan>. These types look like this:

public class Payment {

    @XmlElement(name = "Installment")
    @JsonProperty("Installment")
    private List<Installment> installments = new ArrayList<>();

    @XmlElement(name = "OriginalAmount")
    @JsonProperty("OriginalAmount")
    private BigDecimal originalAmount;

//getters setters, more attributes
}

and....

public class PaymentPlan {
    //(Installment in different package)
    private List<Installment> installments;

    @XmlElement(name = "OriginalAmount")
    @JsonProperty("OriginalAmount")
    private BigDecimal originalAmount;

//getters setters, more attributes
}

I expect that something like this is working...

@Mappings({
    @Mapping(//other mappings...),
    @Mapping(source = "payments", target = "paymentInformation.paymentPlans")
})
ResultResponse originalResponseToResultResponse(OrigResponse originalResponse);

...but I get:

Can't map property java.util.List<Payment> to java.util.List<PaymentPlan>.
Consider to declare/implement a mapping method java.util.List<PaymentPlan> map(java.util.List<Payment> value);

I don't know how to apply this information. First I though I need to declare some extra mapping (in the same mapper class) for the lists, so MapStruct knows how to map each field of the List types like this:

@Mappings({
  @Mapping(source = "payment.originalAmount", target = "paymentInformation.paymentPlan.originalAmount")
})
List<PaymentPlan> paymentToPaymentPlan(List<Payment> payment);

...but I get error messages like

The type of parameter "payment" has no property named "originalAmount".

Obviously I do something completely wrong, since it sound like it does not even recognize the types of the List.

How can I basically map from one List to another similar List? Obviously I somehow need to combine different mapping strategies.

btw: I know how to do it with expression mapping, like...

@Mapping(target = "paymentPlans",expression="java(Helper.mapManually(payments))")

but I guess MapStruct can handle this by iself.

like image 222
Bevor Avatar asked Sep 18 '17 17:09

Bevor


People also ask

How do I map a MapStruct list?

In general, mapping collections with MapStruct works the same way as for simple types. Basically, we have to create a simple interface or abstract class, and declare the mapping methods. Based on our declarations, MapStruct will generate the mapping code automatically.

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.

Does MapStruct work with Lombok?

An example for using the two projects together can be found here. If you are using Lombok 1.18. 16 or newer you also need to add lombok-mapstruct-binding in order to make Lombok and MapStruct work together.

What is MappingTarget in MapStruct?

Annotation Type MappingTargetDeclares a parameter of a mapping method to be the target of the mapping. Not more than one parameter can be declared as MappingTarget . NOTE: The parameter passed as a mapping target must not be null .


1 Answers

I presume you are using version 1.1.0.Final. Your extra mapping is correct, the only difference is that you need to define a mapping without the lists MapStruct will then use that to do the mapping (the example message is a bit misleading for collections).

PaymentPlan paymentToPaymentPlan(Payment payment);

You don't even need the @Mappings as they would be automatically mapped. You might also need to define methods for the Instalment (as they are in different packages).

If you switch to 1.2.0.CR2 then MapStruct can automatically generate the methods for you.

like image 90
Filip Avatar answered Oct 22 '22 06:10

Filip