#1699 add sensible defaults to NullValuePropertyMapping.SET_TO_DEFAULT (#1702)

This commit is contained in:
Sjaak Derksen 2019-01-28 22:47:37 +01:00 committed by GitHub
parent 884ca2507a
commit 0981959ff0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 9 deletions

View File

@ -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.
* <p>
* This means:
* <ol>
* <li>For {@code List} MapStruct generates an {@code ArrayList}</li>
* <li>For {@code Map} a {@code HashMap}</li>
* <li>For arrays an empty array</li>
* <li>For {@code String} {@code ""}</li>
* <li>for primitive / boxed types a representation of {@code 0} or {@code false}</li>
* <li>For all other objects an new instance is created, requiring an empty constructor.</li>
* </ol>
* <p>
* Make sure that a {@link Mapping#defaultValue()} is defined if no empty constructor is available on
* the default value.
*/

View File

@ -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.

View File

@ -934,6 +934,22 @@ public class Type extends ModelElement implements Comparable<Type> {
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

View File

@ -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>

View File

@ -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);
}

View File

@ -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( "" );
}
}