mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#3884 Ensure NullValuePropertyMappingStrategy.SET_TO_DEFAULT
initializes empty collection/map when target is null
Signed-off-by: TangYang <tangyang9464@163.com>
This commit is contained in:
parent
c90c93630e
commit
e4bc1cdf1e
@ -30,6 +30,10 @@
|
|||||||
<@lib.handleLocalVarNullCheck needs_explicit_local_var=directAssignment>
|
<@lib.handleLocalVarNullCheck needs_explicit_local_var=directAssignment>
|
||||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if directAssignment><@wrapLocalVarInCollectionInitializer/><#else><@lib.handleWithAssignmentOrNullCheckVar/></#if></@lib.handleWrite>;
|
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if directAssignment><@wrapLocalVarInCollectionInitializer/><#else><@lib.handleWithAssignmentOrNullCheckVar/></#if></@lib.handleWrite>;
|
||||||
</@lib.handleLocalVarNullCheck>
|
</@lib.handleLocalVarNullCheck>
|
||||||
|
<#if !ext.defaultValueAssignment?? && !sourcePresenceCheckerReference?? && mapNullToDefault>else {
|
||||||
|
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.initTargetObject/></@lib.handleWrite>;
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
</#macro>
|
</#macro>
|
||||||
<#--
|
<#--
|
||||||
wraps the local variable in a collection initializer (new collection, or EnumSet.copyOf)
|
wraps the local variable in a collection initializer (new collection, or EnumSet.copyOf)
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.bugs._3884;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destination type interface for testing null value property mapping strategy with Map properties.
|
||||||
|
*/
|
||||||
|
public interface DestinationType {
|
||||||
|
Map<String, String> getAttributes();
|
||||||
|
|
||||||
|
void setAttributes(Map<String, String> attributes);
|
||||||
|
|
||||||
|
List<String> getItems();
|
||||||
|
|
||||||
|
void setItems(List<String> items);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.bugs._3884;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapper for testing null value property mapping strategy with Map properties.
|
||||||
|
*/
|
||||||
|
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
|
||||||
|
public interface Issue3884Mapper {
|
||||||
|
Issue3884Mapper INSTANCE = Mappers.getMapper( Issue3884Mapper.class );
|
||||||
|
|
||||||
|
void update(@MappingTarget DestinationType destination, SourceType source);
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.bugs._3884;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.ProcessorTest;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for issue 3884: NullValuePropertyMappingStrategy.SET_TO_DEFAULT should set target Map/Collection to default
|
||||||
|
* when source and target are all null.
|
||||||
|
*/
|
||||||
|
@IssueKey("3884")
|
||||||
|
@WithClasses({
|
||||||
|
DestinationType.class,
|
||||||
|
SourceType.class,
|
||||||
|
Issue3884Mapper.class
|
||||||
|
})
|
||||||
|
public class Issue3884Test {
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void shouldSetTargetToDefaultWhenBothSourceAndTargetAreNull() {
|
||||||
|
DestinationType target = new SourceType();
|
||||||
|
SourceType source = new SourceType();
|
||||||
|
|
||||||
|
assertThat( source.getAttributes() ).isNull();
|
||||||
|
assertThat( target.getAttributes() ).isNull();
|
||||||
|
assertThat( source.getItems() ).isNull();
|
||||||
|
assertThat( target.getItems() ).isNull();
|
||||||
|
|
||||||
|
Issue3884Mapper.INSTANCE.update( target, source );
|
||||||
|
|
||||||
|
assertThat( target.getAttributes() ).isEmpty();
|
||||||
|
assertThat( target.getItems() ).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void shouldClearTargetWhenSourceIsNullAndTargetIsInitialized() {
|
||||||
|
DestinationType target = new SourceType();
|
||||||
|
SourceType source = new SourceType();
|
||||||
|
|
||||||
|
Map<String, String> targetAttributes = new HashMap<>();
|
||||||
|
targetAttributes.put( "targetKey", "targetValue" );
|
||||||
|
target.setAttributes( targetAttributes );
|
||||||
|
|
||||||
|
List<String> targetItems = new ArrayList<>();
|
||||||
|
targetItems.add( "targetItem" );
|
||||||
|
target.setItems( targetItems );
|
||||||
|
|
||||||
|
assertThat( source.getAttributes() ).isNull();
|
||||||
|
assertThat( target.getAttributes() ).isNotEmpty();
|
||||||
|
assertThat( source.getItems() ).isNull();
|
||||||
|
assertThat( target.getItems() ).isNotEmpty();
|
||||||
|
|
||||||
|
Issue3884Mapper.INSTANCE.update( target, source );
|
||||||
|
|
||||||
|
assertThat( target.getAttributes() ).isEmpty();
|
||||||
|
assertThat( target.getItems() ).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void shouldCopySourceToTargetWhenSourceIsInitializedAndTargetIsNull() {
|
||||||
|
DestinationType target = new SourceType();
|
||||||
|
SourceType source = new SourceType();
|
||||||
|
|
||||||
|
source.setAttributes( Map.of( "sourceKey", "sourceValue" ) );
|
||||||
|
source.setItems( List.of( "sourceItem" ) );
|
||||||
|
|
||||||
|
assertThat( source.getAttributes() ).isNotEmpty();
|
||||||
|
assertThat( target.getAttributes() ).isNull();
|
||||||
|
assertThat( source.getItems() ).isNotEmpty();
|
||||||
|
assertThat( target.getItems() ).isNull();
|
||||||
|
|
||||||
|
Issue3884Mapper.INSTANCE.update( target, source );
|
||||||
|
|
||||||
|
assertThat( target.getAttributes() ).containsOnly( entry( "sourceKey", "sourceValue" ) );
|
||||||
|
assertThat( target.getItems() ).containsExactly( "sourceItem" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void shouldCopySourceToTargetWhenBothSourceAndTargetAreInitialized() {
|
||||||
|
DestinationType target = new SourceType();
|
||||||
|
SourceType source = new SourceType();
|
||||||
|
|
||||||
|
source.setAttributes( Map.of( "sourceKey", "sourceValue" ) );
|
||||||
|
source.setItems( List.of( "sourceItem" ) );
|
||||||
|
|
||||||
|
Map<String, String> targetAttributes = new HashMap<>();
|
||||||
|
targetAttributes.put( "targetKey", "targetValue" );
|
||||||
|
target.setAttributes( targetAttributes );
|
||||||
|
List<String> targetItems = new ArrayList<>();
|
||||||
|
targetItems.add( "targetItem" );
|
||||||
|
target.setItems( targetItems );
|
||||||
|
|
||||||
|
assertThat( source.getAttributes() ).isNotEmpty();
|
||||||
|
assertThat( target.getAttributes() ).isNotEmpty();
|
||||||
|
assertThat( source.getItems() ).isNotEmpty();
|
||||||
|
assertThat( target.getItems() ).isNotEmpty();
|
||||||
|
|
||||||
|
Issue3884Mapper.INSTANCE.update( target, source );
|
||||||
|
|
||||||
|
assertThat( target.getAttributes() ).containsOnly( entry( "sourceKey", "sourceValue" ) );
|
||||||
|
assertThat( target.getItems() ).containsExactly( "sourceItem" );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.bugs._3884;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source type class implementing DestinationType for testing null value property mapping strategy with Map properties.
|
||||||
|
*/
|
||||||
|
public class SourceType implements DestinationType {
|
||||||
|
private Map<String, String> attributes;
|
||||||
|
private List<String> items;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getAttributes() {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttributes(Map<String, String> attributes) {
|
||||||
|
this.attributes = attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setItems(List<String> items) {
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list != null ) {
|
if ( list != null ) {
|
||||||
target.setStrings( new LinkedHashSet<String>( list ) );
|
target.setStrings( new LinkedHashSet<String>( list ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStrings( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongs() != null ) {
|
if ( target.getLongs() != null ) {
|
||||||
Set<Long> set = stringListToLongSet( source.getStrings() );
|
Set<Long> set = stringListToLongSet( source.getStrings() );
|
||||||
@ -83,6 +86,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set != null ) {
|
if ( set != null ) {
|
||||||
target.setLongs( set );
|
target.setLongs( set );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongs( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsInitialized() != null ) {
|
if ( target.getStringsInitialized() != null ) {
|
||||||
List<String> list1 = source.getStringsInitialized();
|
List<String> list1 = source.getStringsInitialized();
|
||||||
@ -99,6 +105,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list1 != null ) {
|
if ( list1 != null ) {
|
||||||
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStringsInitialized( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongsInitialized() != null ) {
|
if ( target.getLongsInitialized() != null ) {
|
||||||
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
||||||
@ -115,6 +124,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set1 != null ) {
|
if ( set1 != null ) {
|
||||||
target.setLongsInitialized( set1 );
|
target.setLongsInitialized( set1 );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongsInitialized( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsWithDefault() != null ) {
|
if ( target.getStringsWithDefault() != null ) {
|
||||||
List<String> list2 = source.getStringsWithDefault();
|
List<String> list2 = source.getStringsWithDefault();
|
||||||
@ -157,6 +169,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list != null ) {
|
if ( list != null ) {
|
||||||
target.setStrings( new LinkedHashSet<String>( list ) );
|
target.setStrings( new LinkedHashSet<String>( list ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStrings( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongs() != null ) {
|
if ( target.getLongs() != null ) {
|
||||||
Set<Long> set = stringListToLongSet( source.getStrings() );
|
Set<Long> set = stringListToLongSet( source.getStrings() );
|
||||||
@ -173,6 +188,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set != null ) {
|
if ( set != null ) {
|
||||||
target.setLongs( set );
|
target.setLongs( set );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongs( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsInitialized() != null ) {
|
if ( target.getStringsInitialized() != null ) {
|
||||||
List<String> list1 = source.getStringsInitialized();
|
List<String> list1 = source.getStringsInitialized();
|
||||||
@ -189,6 +207,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list1 != null ) {
|
if ( list1 != null ) {
|
||||||
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStringsInitialized( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongsInitialized() != null ) {
|
if ( target.getLongsInitialized() != null ) {
|
||||||
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
||||||
@ -205,6 +226,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set1 != null ) {
|
if ( set1 != null ) {
|
||||||
target.setLongsInitialized( set1 );
|
target.setLongsInitialized( set1 );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongsInitialized( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsWithDefault() != null ) {
|
if ( target.getStringsWithDefault() != null ) {
|
||||||
List<String> list2 = source.getStringsWithDefault();
|
List<String> list2 = source.getStringsWithDefault();
|
||||||
|
@ -67,6 +67,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list != null ) {
|
if ( list != null ) {
|
||||||
target.setStrings( new LinkedHashSet<String>( list ) );
|
target.setStrings( new LinkedHashSet<String>( list ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStrings( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongs() != null ) {
|
if ( target.getLongs() != null ) {
|
||||||
Set<Long> set = stringListToLongSet( source.getStrings() );
|
Set<Long> set = stringListToLongSet( source.getStrings() );
|
||||||
@ -83,6 +86,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set != null ) {
|
if ( set != null ) {
|
||||||
target.setLongs( set );
|
target.setLongs( set );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongs( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsInitialized() != null ) {
|
if ( target.getStringsInitialized() != null ) {
|
||||||
List<String> list1 = source.getStringsInitialized();
|
List<String> list1 = source.getStringsInitialized();
|
||||||
@ -99,6 +105,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list1 != null ) {
|
if ( list1 != null ) {
|
||||||
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStringsInitialized( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongsInitialized() != null ) {
|
if ( target.getLongsInitialized() != null ) {
|
||||||
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
||||||
@ -115,6 +124,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set1 != null ) {
|
if ( set1 != null ) {
|
||||||
target.setLongsInitialized( set1 );
|
target.setLongsInitialized( set1 );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongsInitialized( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsWithDefault() != null ) {
|
if ( target.getStringsWithDefault() != null ) {
|
||||||
List<String> list2 = source.getStringsWithDefault();
|
List<String> list2 = source.getStringsWithDefault();
|
||||||
@ -157,6 +169,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list != null ) {
|
if ( list != null ) {
|
||||||
target.setStrings( new LinkedHashSet<String>( list ) );
|
target.setStrings( new LinkedHashSet<String>( list ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStrings( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongs() != null ) {
|
if ( target.getLongs() != null ) {
|
||||||
Set<Long> set = stringListToLongSet( source.getStrings() );
|
Set<Long> set = stringListToLongSet( source.getStrings() );
|
||||||
@ -173,6 +188,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set != null ) {
|
if ( set != null ) {
|
||||||
target.setLongs( set );
|
target.setLongs( set );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongs( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsInitialized() != null ) {
|
if ( target.getStringsInitialized() != null ) {
|
||||||
List<String> list1 = source.getStringsInitialized();
|
List<String> list1 = source.getStringsInitialized();
|
||||||
@ -189,6 +207,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( list1 != null ) {
|
if ( list1 != null ) {
|
||||||
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
target.setStringsInitialized( new LinkedHashSet<String>( list1 ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setStringsInitialized( new LinkedHashSet<String>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getLongsInitialized() != null ) {
|
if ( target.getLongsInitialized() != null ) {
|
||||||
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
Set<Long> set1 = stringListToLongSet( source.getStringsInitialized() );
|
||||||
@ -205,6 +226,9 @@ public class DomainDtoWithNvmsDefaultMapperImpl implements DomainDtoWithNvmsDefa
|
|||||||
if ( set1 != null ) {
|
if ( set1 != null ) {
|
||||||
target.setLongsInitialized( set1 );
|
target.setLongsInitialized( set1 );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
target.setLongsInitialized( new LinkedHashSet<Long>() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( target.getStringsWithDefault() != null ) {
|
if ( target.getStringsWithDefault() != null ) {
|
||||||
List<String> list2 = source.getStringsWithDefault();
|
List<String> list2 = source.getStringsWithDefault();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user