#3104 Update methods with NullValuePropertyMappingStrategy.IGNORE should use SetterWrapperForCollectionsAndMapsWithNullCheck

This commit is contained in:
Filip Hrisafov 2023-05-01 10:18:23 +02:00
parent a89c34f00c
commit efaa67aadf
3 changed files with 126 additions and 0 deletions

View File

@ -31,6 +31,7 @@ import org.mapstruct.ap.internal.util.accessor.Accessor;
import org.mapstruct.ap.internal.util.accessor.AccessorType; import org.mapstruct.ap.internal.util.accessor.AccessorType;
import static org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem.ALWAYS; import static org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem.ALWAYS;
import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.IGNORE;
import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_DEFAULT; import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_DEFAULT;
import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_NULL; import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_NULL;
@ -177,6 +178,16 @@ public class CollectionAssignmentBuilder {
targetAccessorType.isFieldAssignment() targetAccessorType.isFieldAssignment()
); );
} }
else if ( method.isUpdateMethod() && nvpms == IGNORE ) {
result = new SetterWrapperForCollectionsAndMapsWithNullCheck(
result,
method.getThrownTypes(),
targetType,
ctx.getTypeFactory(),
targetAccessorType.isFieldAssignment()
);
}
else if ( setterWrapperNeedsSourceNullCheck( result ) else if ( setterWrapperNeedsSourceNullCheck( result )
&& canBeMappedOrDirectlyAssigned( result ) ) { && canBeMappedOrDirectlyAssigned( result ) ) {

View File

@ -0,0 +1,77 @@
/*
* 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._3104;
import java.util.Collections;
import java.util.List;
import org.mapstruct.BeanMapping;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.factory.Mappers;
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE)
public interface Issue3104Mapper {
Issue3104Mapper INSTANCE = Mappers.getMapper( Issue3104Mapper.class );
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void update(@MappingTarget Target target, Source source);
class Target {
private List<Child> children = Collections.emptyList();
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
if ( children == null ) {
throw new IllegalArgumentException( "children is null" );
}
this.children = Collections.unmodifiableList( children );
}
}
class Child {
private String myField;
public String getMyField() {
return myField;
}
public void setMyField(String myField) {
this.myField = myField;
}
}
class Source {
private final List<ChildSource> children;
public Source(List<ChildSource> children) {
this.children = children;
}
public List<ChildSource> getChildren() {
return children;
}
}
class ChildSource {
private final String myField;
public ChildSource(String myField) {
this.myField = myField;
}
public String getMyField() {
return myField;
}
}
}

View File

@ -0,0 +1,38 @@
/*
* 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._3104;
import java.util.Collections;
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;
/**
* @author Filip Hrisafov
*/
@IssueKey("3104")
@WithClasses(Issue3104Mapper.class)
class Issue3104Test {
@ProcessorTest
void shouldCorrectlyMapUpdateMappingWithTargetImmutableCollectionStrategy() {
Issue3104Mapper.Target target = new Issue3104Mapper.Target();
Issue3104Mapper.INSTANCE.update( target, new Issue3104Mapper.Source( null ) );
assertThat( target.getChildren() ).isEmpty();
Issue3104Mapper.INSTANCE.update(
target,
new Issue3104Mapper.Source( Collections.singletonList( new Issue3104Mapper.ChildSource( "tester" ) ) )
);
assertThat( target.getChildren() )
.extracting( Issue3104Mapper.Child::getMyField )
.containsExactly( "tester" );
}
}