jengelhart
jengelhart

Reputation: 157

Setting nullValueMappingStrategy on the mapper / mapper config level for categories of mappings

MapStruct documentation has the following to say about the sensible defaults chosen for NullValueMappingStrategy.RETURN_DEFAULT:

Bean mappings: an 'empty' target bean will be returned, with the exception of constants and expressions, they will be populated when present.

Primitives: the default values for primitives will be returned, e.g. false for boolean or 0 for int.

Iterables / Arrays: an empty iterable will be returned.

Maps: an empty map will be returned.

The problem is, we want to be able specify on the @Mapper level that, e.g., Iterables should have NullValueMappingStrategy.RETURN_DEFAULT but not primitives. The reason for this is that an empty iterable is a sensible default for our use case, but 0 is not a sensible default for int. We'd prefer not to have to, e.g., declare:

    @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)

for every iterable we are mapping.

Does MapStruct provide a clean way to do this that I am not finding in the documentation?

Upvotes: 2

Views: 9995

Answers (1)

Sjaak
Sjaak

Reputation: 4160

I think the above line is actually a copy-paste error in the documentation. To make myself clear: the NullValueMappingStrategy only applies to arguments of mapping methods. Not to bean properties. It is not possible to define a primitive argument as source in a bean mapping method.

It is however possible to define non-beans as source of a bean mapping method. Like the mapFrom method below:

package org.mapstruct.ap.test.bugs._xyz;

import java.util.List;

import org.mapstruct.Mapper;
import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.factory.Mappers;

@Mapper( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface XyzMapper {

    XyzMapper INSTANCE = Mappers.getMapper(XyzMapper.class);

    Target map(Source source);

    Target mapFrom( Integer myInt, List<Integer> myList);

    class Source {

        private int myInt;
        private List<Integer> myList;

        public int getMyInt() {
            return myInt;
        }

        public void setMyInt(int myInt) {
            this.myInt = myInt;
        }

        public List<Integer> getMyList() {
            return myList;
        }

        public void setMyList(List<Integer> myList) {
            this.myList = myList;
        }
    }

    class Target {

        private int myInt;
        private List<Integer> myList;

        public int getMyInt() {
            return myInt;
        }

        public void setMyInt(int myInt) {
            this.myInt = myInt;
        }

        public List<Integer> getMyList() {
            return myList;
        }

        public void setMyList(List<Integer> myList) {
            this.myList = myList;
        }
    }


}

When using the NullValueMappingStrategy.RETURN_DEFAULT the mapFrom will return an empty Target just as is specified in the documentation.

This line should be removed from the documentation in relation to the NullValueMappingStrategy: Primitives: the default values for primitives will be returned, e.g. false for boolean or 0 for int.

Upvotes: 0

Related Questions