Search code examples
spring-bootjava-8mapstruct

MapStruct add a new calculated field to the dto


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


Solution

  • 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();
        }
    }