diff --git a/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java b/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java
index 9f698633c..d7f6b7bf1 100644
--- a/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java
+++ b/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java
@@ -29,17 +29,6 @@ package org.mapstruct;
public enum NullValueCheckStrategy {
/**
- * This option includes a null check. When:
- *
- *
- * - a source value is directly assigned to a target
- * - a source value assigned to a target by calling a type conversion on the target first
- *
- *
- * NOTE: mapping methods (generated or hand written) are excluded from this null check. They are intended to
- * handle a null source value as 'valid' input.
- *
- *//**
* This option includes a null check. When:
*
*
@@ -56,6 +45,6 @@ public enum NullValueCheckStrategy {
/**
* This option always includes a null check.
*/
- ALLWAYS,
+ ALWAYS,
}
diff --git a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc
index bf39f7351..b2c91d712 100644
--- a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc
+++ b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc
@@ -1512,6 +1512,33 @@ However, by specifying `nullValueMappingStrategy = NullValueMappingStrategy.RETU
The strategy works in a hierarchical fashion. Setting `nullValueMappingStrategy` on mapping method level will override `@Mapper#nullValueMappingStrategy`, and `@Mapper#nullValueMappingStrategy` will override `@MappingConfig#nullValueMappingStrategy`.
+
+[[checking-source-property-for-null-arguments]]
+=== Controlling checking result for 'null' properties in bean mapping
+
+MapStruct offers control over when to generate a `null` check. By default (`nullValueCheckStrategy = NullValueMappingStrategy.ON_IMPLICIT_CONVERSION`) a `null` check will be generated for:
+
+* direct setting of source value to target value when target is primitive and is source not.
+* applying type conversion and then:
+.. calling the setter on the target.
+.. calling another type conversion and subsequently calling the setter on the target.
+.. calling a mapping method and subsequently calling the setter on the target.
+
+First calling a mapping method on the source property is not protected by a null check. Therefor generated mapping methods will do a null check prior to carrying out mapping on a source property. Handwritten mapping methods must take care of null value checking. They have the possibility to add 'meaning' to `null`. For instance: mapping `null` to a default value.
+
+The option `nullValueCheckStrategy = NullValueMappingStrategy.ALWAYS` will always include a null check when source is non primitive, unless a source presence checker is defined on the source bean.
+
+The strategy works in a hierarchical fashion. `@Mapper#nullValueMappingStrategy` will override `@MappingConfig#nullValueMappingStrategy`.
+
+[[source-presence-check]]
+=== Source presence checking
+Some frameworks generate bean properties that have a source presence checker. Often this is in the form of a method `hasXYZ`, `XYZ` being a property on the source bean in a bean mapping method. MapStruct will call this `hasXYZ` instead of performing a `null` check when it finds such `hasXYZ` method.
+
+[TIP]
+====
+The source presence checker name can be changed in the MapStruct service provider interface (SPI). It can also be deactivated in this way.
+====
+
[[exceptions]]
=== Exceptions
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java
index b13753571..42f2ac0d3 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java
@@ -23,7 +23,6 @@ import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentTy
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.MAPPED_TYPE_CONVERTED;
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED;
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED_MAPPED;
-import static org.mapstruct.ap.internal.prism.NullValueCheckStrategy.ALLWAYS;
import java.util.Arrays;
import java.util.Collections;
@@ -58,6 +57,7 @@ import org.mapstruct.ap.internal.util.Executables;
import org.mapstruct.ap.internal.util.MapperConfiguration;
import org.mapstruct.ap.internal.util.Message;
import org.mapstruct.ap.internal.util.Strings;
+import static org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism.ALWAYS;
/**
* Represents the mapping between a source and target property, e.g. from {@code String Source#foo} to
@@ -344,7 +344,7 @@ public class PropertyMapping extends ModelElement {
else if ( getSourcePresenceCheckerRef() != null ) {
result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
}
- else if ( ALLWAYS.equals( method.getMapperConfiguration().getNullValueCheckStrategy() ) ) {
+ else if ( ALWAYS.equals( method.getMapperConfiguration().getNullValueCheckStrategy() ) ) {
result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
}
else if ( result.getType() == TYPE_CONVERTED
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategy.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategyPrism.java
similarity index 94%
rename from processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategy.java
rename to processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategyPrism.java
index b9917b8f8..d59862ca7 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategy.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategyPrism.java
@@ -24,8 +24,8 @@ package org.mapstruct.ap.internal.prism;
*
* @author Sean Huang
*/
-public enum NullValueCheckStrategy {
+public enum NullValueCheckStrategyPrism {
ON_IMPLICIT_CONVERSION,
- ALLWAYS;
+ ALWAYS;
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java b/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java
index 5bf917a98..d52b0d8e0 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java
@@ -32,7 +32,7 @@ import org.mapstruct.ap.internal.prism.MapperConfigPrism;
import org.mapstruct.ap.internal.prism.MapperPrism;
import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism;
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
-import org.mapstruct.ap.internal.prism.NullValueCheckStrategy;
+import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
/**
* Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and
@@ -136,12 +136,12 @@ public class MapperConfiguration {
}
}
- public NullValueCheckStrategy getNullValueCheckStrategy() {
+ public NullValueCheckStrategyPrism getNullValueCheckStrategy() {
if ( mapperConfigPrism != null && mapperPrism.values.nullValueCheckStrategy() == null ) {
- return NullValueCheckStrategy.valueOf( mapperConfigPrism.nullValueCheckStrategy() );
+ return NullValueCheckStrategyPrism.valueOf( mapperConfigPrism.nullValueCheckStrategy() );
}
else {
- return NullValueCheckStrategy.valueOf( mapperPrism.nullValueCheckStrategy() );
+ return NullValueCheckStrategyPrism.valueOf( mapperPrism.nullValueCheckStrategy() );
}
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java
index cee061e00..9c127a3aa 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java
@@ -27,7 +27,7 @@ import org.mapstruct.factory.Mappers;
*
* @author Sjaak Derksen
*/
-@Mapper( nullValueCheckStrategy = NullValueCheckStrategy.ALLWAYS )
+@Mapper( nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS )
public abstract class RockFestivalMapper {
public static final RockFestivalMapper INSTANCE = Mappers.getMapper( RockFestivalMapper.class );
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java
index 9cb829432..790ad035d 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java
@@ -24,7 +24,7 @@ import org.mapstruct.NullValueCheckStrategy;
*
* @author Sjaak Derksen
*/
-@MapperConfig( nullValueCheckStrategy = NullValueCheckStrategy.ALLWAYS )
+@MapperConfig( nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS )
public interface RockFestivalMapperConfig {
}