Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapstruct - ignore field by name in whole project

I've got project, where I often map dto -> db model. Almost all my db models have some additional fields, like version, which are never mapped from dto.

Is there any possibility or elegant workaround to ignore target fields globally only by theirs names?

For now I have to use @Mapping(target = "version", ignore = true). Cannot use @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE), because I'd like to get warns or errors when I accidentally omit any important property. I control default behavior with '-Amapstruct.unmappedTargetPolicy=WARN', which I change for ERROR during developing new functions.

Some people may say that these are just warnings, but when there are many of them, it makes it harder to spot mistakes.

Mapstruct 1.3.1.Final, probably will move to 1.4.1.Final in nearest future. Searched through the docs, but couldn't find anything useful.

Thanks in advance for your answers :)

like image 977
rav137 Avatar asked Oct 19 '20 08:10

rav137


1 Answers

Some people may say that these are just warnings, but when there are many of them, it makes it harder to spot mistakes.

First of all, I am glad you don't ignore warnings.

As of MapStruct 1.4 you can create an annotation that is composed of multiple mappings. Read more at the documentation of MapStruct 1.4.1. 3.2. Mapping Composition (experimental). This configuration can also be shared (11.3. Shared configurations).

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "version", ignore = true)
public @interface WithoutVersion { }
@Mapper
public interface DtoMapper {
   
   @WithoutVersion
   Dto entityToDto(Entity entity)
}

This get useful in case of multiple fields to be ignored. The biggest advantage is that you take a control over mapping through the explicit use of the annotation and not a global configuration.

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "version", ignore = true)
@Mapping(target = "createdAt", ignore = true)
@Mapping(target = "modifiedAt", ignore = true)
@Mapping(target = "id", ignore = true)
public @interface WithoutMetadata { }
@Mapper
public interface DtoMapper {
   
   @WithoutMetadata 
   Dto entityToDto(Entity entity)
}
like image 152
Nikolas Charalambidis Avatar answered Oct 21 '22 01:10

Nikolas Charalambidis