4

I have the following mapper

@Mapper(config = MappingConfig.class)
public interface PokerRoomMapper {

  @Mapping(target = "phase", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
  PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);

}

The pokerRoomDto which is passed to it has a "phase" field which can be null. I want this field to be ignored when it is null. But right now the "null" value still gets mapped to the pokerRoom entity.

If I just ignore the field in the mapper it works and the default value for phase in PokerRoom stays untouched however I dont want to always ignore it.

@Mapper(config = MappingConfig.class)
public interface PokerRoomMapper {

  @Mapping(target = "phase", ignore = true)
  PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);

}
JangoCG
  • 823
  • 10
  • 23
  • 1
    Does the phase on `PokerRoom` have default value? If not then I am not sure how you workout that the mapping is not working. If mapstruct ignores a field during mapping which has no default value then it will be null after mapping anyway – madteapot Mar 01 '21 at 16:04
  • Yes it has a default value which correctly stays untouched if I use the second Mapper where I just ignore it. – JangoCG Mar 01 '21 at 16:09
  • 3
    according to javadoc for [NullValuePropertyMappingStrategy](https://mapstruct.org/documentation/1.3/api/org/mapstruct/NullValuePropertyMappingStrategy.html) **only applies to update methods: methods that update a pre-existing target (annotated with @MappingTarget)**. Have a look at https://stackoverflow.com/questions/54174437/mapstruct-how-to-set-different-null-strategy-for-different-mapping-methods and https://stackoverflow.com/questions/46669594/map-struct-when-source-is-null-target-should-not-be-set-to-null – madteapot Mar 01 '21 at 16:31

2 Answers2

4

This works as designed. NullValuePropertyMappingStrategy is only applied to update method. It is not used for normal mappings.

I think that you are looking for NullValueCheckStrategy, if you use NullValueCheckStrategy#ALWAYS then MapStruct will always do a null check non the PokerRoomDto and only invoke the setter on the PokerRoom if the value was not null

Filip
  • 19,269
  • 7
  • 51
  • 60
0

If you initialise your field at declaration and want to keep that value, I've come up with a solution. A bit hacky, not very general (depends on generated variable name), but works. Assuming:

class PokerRoom {
    Integer phase = 0;
}

You can use

@Mapping(target = "phase", defaultExpression = "java( pokerRoom.getPhase() )")
PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);

A simpler solution would be to use the same constant you use at field declaration.

@Mapping(target = "phase", defaultValue = "0")
PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);
Hawk
  • 2,042
  • 8
  • 16