Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapstruct: Ignore specific field only for collection mapping

I am using following mapper to map entities:

public interface AssigmentFileMapper {

AssigmentFileDTO assigmentFileToAssigmentFileDTO(AssigmentFile assigmentFile);

AssigmentFile assigmentFileDTOToAssigmentFile(AssigmentFileDTO assigmentFileDTO);

@Mapping(target = "data", ignore = true)
List<AssigmentFileDTO> assigmentFilesToAssigmentFileDTOs(List<AssigmentFile> assigmentFiles);

List<AssigmentFile> assigmentFileDTOsToAssigmentFiles(List<AssigmentFileDTO> assigmentFileDTOs);
}

I need to ignore the "data" field only for entities that mapped as collection. But it looks like @Mapping works only for single entities. Also I've noticed that generated method assigmentFilesToAssigmentFileDTOs just uses assigmentFileToAssigmentFileDTO in for-loop. Is there any solution for that?

like image 339
Dmitry Kach Avatar asked Mar 14 '17 13:03

Dmitry Kach


People also ask

How do you ignore fields in Mapper?

We can ignore unmapped properties in several mappers by setting the unmappedTargetPolicy via @MapperConfig to share a setting across several mappers.

Is MapStruct slow?

Throughput. In throughput mode, MapStruct was the fastest of the tested frameworks, with JMapper a close second.

What is @InheritInverseConfiguration?

Annotation Type InheritInverseConfiguration An inverse mapping method is a method which has the annotated method's source type as target type (return type or indicated through a parameter annotated with MappingTarget ) and the annotated method's target type as source type.


1 Answers

MapStruct uses the assignment that it can find for the collection mapping. In order to achieve what you want you will have to define a custom method where you are going to ignore the data field explicitly and then use @IterableMapping(qualifiedBy) or @IterableMapping(qualifiedByName) to select the required method.

Your mapper should look like:

public interface AssigmentFileMapper {

    AssigmentFileDTO assigmentFileToAssigmentFileDTO(AssigmentFile assigmentFile);

    AssigmentFile assigmentFileDTOToAssigmentFile(AssigmentFileDTO assigmentFileDTO);

    @IterableMapping(qualifiedByName="mapWithoutData")
    List<AssigmentFileDTO> assigmentFilesToAssigmentFileDTOs(List<AssigmentFile> assigmentFiles);

    List<AssigmentFile> assigmentFileDTOsToAssigmentFiles(List<AssigmentFileDTO> assigmentFileDTOs);

    @Named("mapWithoutData")
    @Mapping(target = "data", ignore = true)
    AssignmentFileDto mapWithouData(AssignmentFile source)

}

You should use org.mapstruct.Named and not javax.inject.Named for this to work. You can also define your own annotation by using org.mapstruct.Qualifier

You can find more information here in the documentation.

like image 87
Filip Avatar answered Oct 18 '22 15:10

Filip