Skip to content

Commit 0981959

Browse files
authored
mapstruct#1699 add sensible defaults to NullValuePropertyMapping.SET_TO_DEFAULT (mapstruct#1702)
1 parent 884ca25 commit 0981959

6 files changed

Lines changed: 41 additions & 9 deletions

File tree

core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ public enum NullValuePropertyMappingStrategy {
3333

3434
/**
3535
* If a source bean property equals {@code null} the target bean property will be set to its default value.
36+
* <p>
37+
* This means:
38+
* <ol>
39+
* <li>For {@code List} MapStruct generates an {@code ArrayList}</li>
40+
* <li>For {@code Map} a {@code HashMap}</li>
41+
* <li>For arrays an empty array</li>
42+
* <li>For {@code String} {@code ""}</li>
43+
* <li>for primitive / boxed types a representation of {@code 0} or {@code false}</li>
44+
* <li>For all other objects an new instance is created, requiring an empty constructor.</li>
45+
* </ol>
46+
* <p>
3647
* Make sure that a {@link Mapping#defaultValue()} is defined if no empty constructor is available on
3748
* the default value.
3849
*/

documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,11 +2134,15 @@ The strategy works in a hierarchical fashion. Setting `nullValueMappingStrategy`
21342134
[[mapping-result-for-null-properties]]
21352135
=== Controlling mapping result for 'null' properties in bean mappings (update mapping methods only).
21362136

2137-
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.
2137+
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'.
21382138

2139-
By default the source property will be set to null. However:
2139+
By default the target property will be set to null.
21402140

2141-
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`.
2141+
However:
2142+
2143+
1. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result can be altered to return *default* values.
2144+
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`.
2145+
For all other objects an new instance is created. Please note that a default constructor is required. If not available, use the `@Mapping#defaultValue`.
21422146

21432147
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.
21442148

processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,22 @@ public String getNull() {
934934
throw new UnsupportedOperationException( getName() );
935935
}
936936

937+
public String getSensibleDefault() {
938+
if ( isPrimitive() ) {
939+
return getNull();
940+
}
941+
else if ( "String".equals( getName() ) ) {
942+
return "\"\"";
943+
}
944+
else {
945+
if ( isNative() ) {
946+
// must be boxed, since primitive is already checked
947+
return typeFactory.getType( typeUtils.unboxedType( typeMirror ) ).getNull();
948+
}
949+
}
950+
return null;
951+
}
952+
937953
@Override
938954
public int hashCode() {
939955
// javadoc typemirror: "Types should be compared using the utility methods in Types. There is no guarantee

processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ Performs a default assignment with a default value.
161161
new <@includeModel object=ext.targetType.implementationType/>()
162162
<#elseif ext.targetType.arrayType>
163163
new <@includeModel object=ext.targetType.componentType/>[0]
164+
<#elseif ext.targetType.sensibleDefault??>
165+
${ext.targetType.sensibleDefault}
164166
<#else>
165167
new <@includeModel object=ext.targetType/>()
166168
</#if>

processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public interface UserMapper {
3838

3939
@InheritInverseConfiguration
4040
@BeanMapping( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT )
41-
@Mapping( target = "phone", source = "contactDataDTO.phone", defaultValue = "0" )
4241
void updateUserFromUserAndDefaultDTO(UserDTO userDTO, @MappingTarget User user);
4342

4443
}

processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
@Generated(
1414
value = "org.mapstruct.ap.MappingProcessor",
15-
date = "2019-01-27T12:40:32+0100",
16-
comments = "version: , compiler: Eclipse JDT (Batch) 1.2.100.v20160418-1457, environment: Java 1.8.0_181 (Oracle Corporation)"
15+
date = "2019-01-28T21:17:39+0100",
16+
comments = "version: , compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
1717
)
1818
public class UserMapperImpl implements UserMapper {
1919

@@ -116,7 +116,7 @@ public void updateUserFromUserAndDefaultDTO(UserDTO userDTO, User user) {
116116
user.setAddress( address );
117117
}
118118
else {
119-
user.setAddress( new String() );
119+
user.setAddress( "" );
120120
}
121121
String phone = userDTOContactDataDTOPhone( userDTO );
122122
if ( phone != null ) {
@@ -130,13 +130,13 @@ public void updateUserFromUserAndDefaultDTO(UserDTO userDTO, User user) {
130130
user.setEmail( email );
131131
}
132132
else {
133-
user.setEmail( new String() );
133+
user.setEmail( "" );
134134
}
135135
if ( userDTO.getName() != null ) {
136136
user.setName( userDTO.getName() );
137137
}
138138
else {
139-
user.setName( new String() );
139+
user.setName( "" );
140140
}
141141
}
142142

0 commit comments

Comments
 (0)