#3495 when updating targets with collections without a setter, clear them only if the null check or condition is satisfied

This commit is contained in:
thunderhook 2024-01-03 23:26:38 +01:00
parent 7e6fee8714
commit e0576f654b
4 changed files with 93 additions and 5 deletions

View File

@ -10,10 +10,10 @@
<@lib.sourceLocalVarAssignment/>
if ( ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing /> != null ) {
<@lib.handleExceptions>
<#if ext.existingInstanceMapping>
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.clear();
</#if>
<@lib.handleLocalVarNullCheck needs_explicit_local_var=false>
<#if ext.existingInstanceMapping>
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.clear();
</#if>
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.<#if ext.targetType.collectionType>addAll<#else>putAll</#if>( <@lib.handleWithAssignmentOrNullCheckVar/> );
</@lib.handleLocalVarNullCheck>
</@lib.handleExceptions>

View File

@ -44,11 +44,12 @@ public class Issue289Test {
Source source = new Source();
source.setCollection( null );
TargetWithoutSetter target = new TargetWithoutSetter();
target.getCollection().add( new TargetElement() );
TargetElement existingElement = new TargetElement();
target.getCollection().add( existingElement );
Issue289Mapper.INSTANCE.sourceToTargetWithoutSetter( source, target );
assertThat( target.getCollection() ).isEmpty();
assertThat( target.getCollection() ).containsExactly( existingElement );
}
@ProcessorTest

View File

@ -0,0 +1,54 @@
/*
* 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._3495;
import java.util.ArrayList;
import java.util.List;
import org.mapstruct.Condition;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
@Mapper
public interface Issue3495Mapper {
Issue3495Mapper INSTANCE = Mappers.getMapper( Issue3495Mapper.class );
@Mapping(target = "names", source = "names", conditionQualifiedByName = "alwaysFalse")
void update(Source source, @MappingTarget TargetWithoutSetter target);
@Condition
@Named("alwaysFalse")
default boolean alwaysFalse(@MappingTarget TargetWithoutSetter target) {
return false;
}
class Source {
private List<String> names;
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
}
class TargetWithoutSetter {
private final List<String> names = new ArrayList<>();
public List<String> getNames() {
return names;
}
}
}

View File

@ -0,0 +1,33 @@
/*
* 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._3495;
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 Oliver Erhart
*/
@IssueKey("3495")
@WithClasses(Issue3495Mapper.class)
class Issue3495Test {
@ProcessorTest
void shouldNotClearCollectionBecauseConditionWasNotMet() {
Issue3495Mapper.Source source = new Issue3495Mapper.Source();
Issue3495Mapper.TargetWithoutSetter target = new Issue3495Mapper.TargetWithoutSetter();
target.getNames().add( "name" );
Issue3495Mapper.INSTANCE.update( source, target );
assertThat( target ).isNotNull();
assertThat( target.getNames() ).containsExactly( "name" );
}
}