简体   繁体   中英

Mapstruct - ignore fields from nested collection - not working when cloning the object

I have the following entity classes and similar DTO classes:

class Car {
    Long id;
    List<Owner> ownerList;
}

class Owner {
    Long id;
    String name;
}

I used MapStruct with following mappings to :

  1. copy to CarDto without IDs
    @Mapping(target = "id", ignore = true)
    @Mapping(target = "ownerList", qualifiedByName = "withoutIdDto")
    CarDto carToCarDto(Car car);

    @Named("withoutIdDto")
    @Mapping(target = "id", ignore = true)
    OwnerDto mapOwnerDtoWithoutId(Owner owner);
  1. clone without IDs
    @Mapping(target = "id", ignore = true) //ignore Car.id
    @Mapping(target = "ownerList", qualifiedByName = "withoutId")
    Car copyCar(Car car);

    @Named("withoutId")
    @Mapping(target = "id", ignore = true) //ignore Owner.id
    Owner mapOwnerWithoutId(Owner owner);

The problem is:

The generated mapper for carToCarDto() is calling mapOwnerDtoWithoutId() but copyCar method is not calling mapOwnerWithoutId(). Here's the snippet of generated methods:

public Car copyCar(Car car) {
    if (car == null) {
        return null;
    } else {
        Car car1 = new Car();
        List<Owner> list = car.getOwnerList();
        if (list != null) {
            car1.setOwnerList(new ArrayList(list)); // no reference to mapOwnerWithoutId
        }

        return car1;
    }
}

public CarDto carToCarDto(Car car) {
    if (car == null) {
        return null;
    } else {
        CarDto carDto = new CarDto();
        carDto.setOwnerList(this.ownerListToOwnerDtoList(car.getOwnerList())); //ownerListToOwnerDtoList () calls mapOwnerDtoWithoutId
        return carDto;
    }
}

I've following project to reproduce this. Any idea how to fix the test CarMapperTest?

https://github.com/gtiwari333/mapstruct-failing-test-same-object-copy

There's a difference in the way MapStruct handles 1. Lists where source and target elements are the same (in line) 2. Lists where source and target are different.

Personally I don't like that difference, but it has been there for a long time. I'm a bit afraid that when we change this (and always do 2.) we might break some implementations.

Having said that I still think MapStruct should prefer an available method over a direct mapping. Please write an issue for that on our GitHub and refer to this one.

Now, a workaround for this is to define an intermediate mapping method like this: List map(List s). MapStruct will generate the implementation for that one and call it as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM