mapstruct - Propagate parent field value to collection of nested objects

antohoho :

Is it possible to propagate value form a parent object to collection of nested objects? For example

Source DTO classes

class CarDTO {
  private String name;
  private long userId;
  private Set<WheelDto> wheels; 
};

class WheelDto {
  private String name;
}

Target entity classes

class Car {
  private String name;
  private long userId;
  private Set<Wheel> wheels; 
};

class Wheel {
  private String name;
  private long lastUserId;
}

As you could see I do not have lastUserId on WheelDto, hence I would like to map userId from CarDto to lastUserId on WheelDto on each object in a wheels collection I tried

@Mapping(target = "wheels.lastUserId", source = "userId") 

but no luck

Filip :

Currently it is not possible to pass a property. However, you could solve this via @AfterMapping and / or @Context.

Update Wheel after Car mapping

This would though mean that you would need to iterate twice over the Wheel. It can look like

@Mapper
public interface CarMapper {

    Car map(CarDto carDto);

    @AfterMapping
    default void afterCarMapping(@MappingTarget Car car, CarDto carDto) {
        car.getWheels().forEach(wheel -> wheel.setLastUserId(carDto.getUserId()));
    }
}

Pass @Context while mapping wheel to have state during the mapping

If you want to iterate only once through the Wheel then you can pass a @Context object that would get the userId from the CarDto before mapping the car and then set it on the Wheel in an after mapping. This mapper can look like:

@Mapper
public interface CarMapper {

    Car map(CarDto carDto, @Context CarContext context);

    Wheel map(WheelDto wheelDto, @Context CarContext context);

}

public class CarContext {

    private String lastUserId;

    @BeforeMapping
    public void beforeCarMapping(CarDto carDto) {
        this.lastUserId = carDto.getUserId();
    }

    @AfterMapping
    public void afterWheelMapping(@MappingTarget Wheel wheel) {
        wheel.setLastUserId(lastUserId);
    }

}

The CarContext would be passed to the wheel mapping method.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=88582&siteId=1