diff --git a/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java b/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java
index 6db84814c..9e06e723b 100644
--- a/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java
+++ b/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java
@@ -33,6 +33,17 @@ public enum NullValuePropertyMappingStrategy {
/**
* If a source bean property equals {@code null} the target bean property will be set to its default value.
+ *
+ * This means:
+ *
+ * - For {@code List} MapStruct generates an {@code ArrayList}
+ * - For {@code Map} a {@code HashMap}
+ * - For arrays an empty array
+ * - For {@code String} {@code ""}
+ * - for primitive / boxed types a representation of {@code 0} or {@code false}
+ * - For all other objects an new instance is created, requiring an empty constructor.
+ *
+ *
* Make sure that a {@link Mapping#defaultValue()} is defined if no empty constructor is available on
* the default value.
*/
diff --git a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc
index 3c1ea5649..46a996353 100644
--- a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc
+++ b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc
@@ -2134,11 +2134,15 @@ The strategy works in a hierarchical fashion. Setting `nullValueMappingStrategy`
[[mapping-result-for-null-properties]]
=== Controlling mapping result for 'null' properties in bean mappings (update mapping methods only).
-MapStruct offers control over the property to set in an `@MappingTarget` annotated target bean when the source property equals `null` or the presence check method yields absent.
+MapStruct offers control over the property to set in an `@MappingTarget` annotated target bean when the source property equals `null` or the presence check method results in 'absent'.
-By default the source property will be set to null. However:
+By default the target property will be set to null.
-1. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result can be altered to return *default* values. Please note that a default constructor is required. If not available, use the `@Mapping#defaultValue`. For `List` MapStruct generates an `ArrayList`, for `Map` mapstruct generates a `HashMap`.
+However:
+
+1. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result can be altered to return *default* values.
+For `List` MapStruct generates an `ArrayList`, for `Map` a `HashMap`, for arrays an empty array, for `String` `""` and for primitive / boxed types a representation of `false` or `0`.
+For all other objects an new instance is created. Please note that a default constructor is required. If not available, use the `@Mapping#defaultValue`.
2. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result will be equal to the original value of the `@MappingTarget` annotated target.
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java
index 8097b15e6..5992a687b 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java
@@ -934,6 +934,22 @@ public class Type extends ModelElement implements Comparable {
throw new UnsupportedOperationException( getName() );
}
+ public String getSensibleDefault() {
+ if ( isPrimitive() ) {
+ return getNull();
+ }
+ else if ( "String".equals( getName() ) ) {
+ return "\"\"";
+ }
+ else {
+ if ( isNative() ) {
+ // must be boxed, since primitive is already checked
+ return typeFactory.getType( typeUtils.unboxedType( typeMirror ) ).getNull();
+ }
+ }
+ return null;
+ }
+
@Override
public int hashCode() {
// javadoc typemirror: "Types should be compared using the utility methods in Types. There is no guarantee
diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl
index 8fe5c44fa..96ecd953b 100644
--- a/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl
+++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl
@@ -161,6 +161,8 @@ Performs a default assignment with a default value.
new <@includeModel object=ext.targetType.implementationType/>()
<#elseif ext.targetType.arrayType>
new <@includeModel object=ext.targetType.componentType/>[0]
+ <#elseif ext.targetType.sensibleDefault??>
+ ${ext.targetType.sensibleDefault}
<#else>
new <@includeModel object=ext.targetType/>()
#if>
diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java
index 10ed334c0..38800dc75 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java
@@ -38,7 +38,6 @@ public interface UserMapper {
@InheritInverseConfiguration
@BeanMapping( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT )
- @Mapping( target = "phone", source = "contactDataDTO.phone", defaultValue = "0" )
void updateUserFromUserAndDefaultDTO(UserDTO userDTO, @MappingTarget User user);
}
diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java
index 9c62462f5..811fca4a5 100644
--- a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java
+++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java
@@ -12,8 +12,8 @@ import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
- date = "2019-01-27T12:40:32+0100",
- comments = "version: , compiler: Eclipse JDT (Batch) 1.2.100.v20160418-1457, environment: Java 1.8.0_181 (Oracle Corporation)"
+ date = "2019-01-28T21:17:39+0100",
+ comments = "version: , compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
)
public class UserMapperImpl implements UserMapper {
@@ -116,7 +116,7 @@ public class UserMapperImpl implements UserMapper {
user.setAddress( address );
}
else {
- user.setAddress( new String() );
+ user.setAddress( "" );
}
String phone = userDTOContactDataDTOPhone( userDTO );
if ( phone != null ) {
@@ -130,13 +130,13 @@ public class UserMapperImpl implements UserMapper {
user.setEmail( email );
}
else {
- user.setEmail( new String() );
+ user.setEmail( "" );
}
if ( userDTO.getName() != null ) {
user.setName( userDTO.getName() );
}
else {
- user.setName( new String() );
+ user.setName( "" );
}
}