13

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.

2 Answers 2

11

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());
Sign up to request clarification or add additional context in comments.

2 Comments

An example would be really useful
I've added an example that showcases the idea
1

I didnt even have to use context. I could simply pass the additional parameter and the mapper recognises it in the build.

    NotMORV2Entity toNotMorV2Entity(ReEntity reEntity, int glAccountTypeId);

Please also see this to understand more.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.