I'm trying to map an entity Order
to a OrderDTO
using MapStruct. I want to add to OrderDTO
a new field total
, this field is not available in the original entity Order
and should be calculated using the information available in the Order
(order entries price, quantity, taxes...).
I created a new field total
in the OrderDTO
and I'm trying to map it by adding a default method to the mapper interface:
public interface OrderMapper {
...
default BigDecimal orderToTotal(Order order){
return logicToCalculateTotal();
}
}
When I lunch the build MapStruct launch the error
Unmapped target property: "total".
Any idea how to solve this problem?
Thanks
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.
Enclosing class: MappingConstants public static final class MappingConstants.ComponentModel extends Object. Specifies the component model constants to which the generated mapper should adhere. It can be used with the annotation Mapper.componentModel() or MapperConfig.componentModel()
AST modifications are not foreseen by Java annotation processing API, so quite some trickery was required within Lombok as well as MapStruct to make both of them work together. Essentially, MapStruct will wait until Lombok has done all its amendments before generating mapper classes for Lombok-enhanced beans.
Java Prime Pack Using Mapstruct we can pass the default value in case source property is null using defaultValue attribute of @Mapping annotation.
There are multiple way to achieve what you need. The first way is to use @AfterMapping
or @BeforeMapping
. If you go with this your code will look like:
public interface OrderMapper {
@Mapping(target = "total", ignore = true) // Needed so the warning does not shown, it is mapped in calculateTotal
OrderDto map(Order order);
@AfterMapping // or @BeforeMapping
default void calculateTotal(Order order, @MappingTarget OrderDto dto) {
dto.setTotal(logicToCalculateTotal());
}
}
The alternative approach would be to do like you started, but you have to say that total
is mapped from the Order
.
Your mapper in the alternative approach would be:
public interface OrderMapper {
@Mapping(target = "total", source = "order")// the source should be equal to the property name
OrderDto map(Order order);
default BigDecimal orderToTotal(Order order) {
return logicToCalculateTotal();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With