10

Haven't figured out how to pass in additional arguments or an alternative.

Currently I'm mapping an Order and OrderLines. Both objects are different and need @mappings. Example I have an Order and OrderRequest object both are different and need @Mappings annotation to map the values, same with OrderLines.

I've created the following mappers

  • OrderMapper (uses = OrderLineMappers.class)
  • OrderLineMappers (uses = OrderLineMapper.class)
  • OrderLineMapper

So my issue is the OrderLine needs the OrderId from the Order object. However in the OrderLineMapper it's passing in the OrderLine and not the Order. How can I send the OrderId to the OrderLineMapper? Currently I have the OrderMapper doing an @AfterMapper, looping through the orderLines and populating with the OrderId.

Any help would be great.

Class OrderMapper

@Mapper(componentModel = "spring",  uses = {OrderLineMappers.class})
public abstract class OrderMapper {

@AfterMapping
protected void orderRequestFromOrder( Order order, @MappingTarget 
OrderRequest orderRequest ) {

    //Wanting to do this at the OrderLineMapper class and not here
    String orderId = order.getId();
    List<OrderLineRequest> lines = orderRequest.getOrderLines();
    List<OrderLineRequest> updatedLines = new ArrayList<>();
    for (OrderLineRequest line : lines) {
        line.setOrderId(orderId);
        updatedLines.add(line);
    }
    orderRequest.setOrderLines(updatedLines);
}

@Mappings({
    @Mapping( source = "orderId", target = "id" ),
    @Mapping( source = "orderNumber", target = "order_number" ),
    @Mapping( source = "orderLines", target = "orderLines")
})
public abstract Order orderRequestToOrder(OrderRequest orderRequest);

Class OrderLineMappers

@Mapper(componentModel = "spring",  uses = {OrderLineMapper.class})
public interface OrderLineMappers {

    List<OrderLine> orderLines(List<OrderLineRequest> orderLineRequest);

    @InheritInverseConfiguration
    List<OrderLineRequest> orderLineRequests(List<OrderLine> orderLine); 

}

Class OrderLineMapper

@Mapper(componentModel = "spring")
public abstract class OrderLineMapper {
    @Mappings({
        @Mapping( target = "orderId", source = "orderLineId" ),
        @Mapping( target = "order_line_number", source = "orderLineNumber")

    })
    public abstract OrderLine orderLineRequestToOrderLine(OrderLineRequest orderLineRequest);
}

Again just trying to pass in the OrderId to the OrderLineMapper. Not sure how to do this.

shadley
  • 145
  • 2
  • 2
  • 6

1 Answers1

10

You can't really do this. What you can do instead is to use the @Context and perform your logic in it. You can have @AfterMapping and @BeforeMapping in your context where you can store the Order id and use that during its execution

e.g.

public class OrderMappingContext {

    protected String currentOrderId;

    @BeforeMapping
    public void startMappingOrder(@MappingTarget Order order, OrderRequest request) {
        this.currentOrderId = request.getId();
    }

    @AfterMapping
    public void finishOrderMapping(@MappingTarget Order order) {
        this.currentOrderId = null;
    }

    @AfterMapping
    public void afterOrderLineMapping(@MappingTarget OrderLine orderLine) {
        orderLine.setOrderId(this.currentOrderId);
    }
}

Your mappers will then look like:

@Mapper(componentModel = "spring",  uses = {OrderLineMappers.class})
public abstract class OrderMapper {



    @Mapping( source = "orderId", target = "id" ),
    @Mapping( source = "orderNumber", target = "order_number" ),
    @Mapping( source = "orderLines", target = "orderLines")
    public abstract Order orderRequestToOrder(OrderRequest orderRequest, @Context OrderMappingContext context);
@Mapper(componentModel = "spring",  uses = {OrderLineMapper.class})
public interface OrderLineMappers {

    List<OrderLine> orderLines(List<OrderLineRequest> orderLineRequest, @Context OrderMappingContext context);

    @InheritInverseConfiguration
    List<OrderLineRequest> orderLineRequests(List<OrderLine> orderLine); 

}
@Mapper(componentModel = "spring")
public abstract class OrderLineMapper {

    @Mapping( target = "orderId", source = "orderLineId" ),
    @Mapping( target = "order_line_number", source = "orderLineNumber")
    public abstract OrderLine orderLineRequestToOrderLine(OrderLineRequest orderLineRequest, @Context OrderMappingContext context);
}

On the invocation side you will do something like

orderMapper.orderRequestToOrder(request, new OrderMappingContext());
Filip
  • 19,269
  • 7
  • 51
  • 60