mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#3806: Properly apply NullValuePropertyMappingStrategy.IGNORE
for collections / maps without setters
Signed-off-by: TangYang <tangyang9464@163.com>
This commit is contained in:
parent
5464c3cff8
commit
8fc97f5f62
@ -240,6 +240,7 @@ public class CollectionAssignmentBuilder {
|
||||
result,
|
||||
method.getThrownTypes(),
|
||||
targetType,
|
||||
nvpms,
|
||||
targetAccessorType.isFieldAssignment()
|
||||
);
|
||||
}
|
||||
|
@ -9,9 +9,12 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem;
|
||||
import org.mapstruct.ap.internal.model.common.Assignment;
|
||||
import org.mapstruct.ap.internal.model.common.Type;
|
||||
|
||||
import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.IGNORE;
|
||||
|
||||
/**
|
||||
* This wrapper handles the situation were an assignment must be done via a target getter method because there
|
||||
* is no setter available.
|
||||
@ -26,6 +29,14 @@ import org.mapstruct.ap.internal.model.common.Type;
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public class GetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAndMaps {
|
||||
private final boolean ignoreMapNull;
|
||||
|
||||
public GetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment,
|
||||
List<Type> thrownTypesToExclude,
|
||||
Type targetType,
|
||||
boolean fieldAssignment) {
|
||||
this( decoratedAssignment, thrownTypesToExclude, targetType, null, fieldAssignment );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param decoratedAssignment source RHS
|
||||
@ -36,6 +47,7 @@ public class GetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd
|
||||
public GetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment,
|
||||
List<Type> thrownTypesToExclude,
|
||||
Type targetType,
|
||||
NullValuePropertyMappingStrategyGem nvpms,
|
||||
boolean fieldAssignment) {
|
||||
|
||||
super(
|
||||
@ -44,6 +56,7 @@ public class GetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd
|
||||
targetType,
|
||||
fieldAssignment
|
||||
);
|
||||
this.ignoreMapNull = nvpms == IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,4 +67,8 @@ public class GetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd
|
||||
}
|
||||
return imported;
|
||||
}
|
||||
|
||||
public boolean isIgnoreMapNull() {
|
||||
return ignoreMapNull;
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,13 @@
|
||||
<@lib.sourceLocalVarAssignment/>
|
||||
if ( ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing /> != null ) {
|
||||
<@lib.handleExceptions>
|
||||
<#if ext.existingInstanceMapping>
|
||||
<#if ext.existingInstanceMapping && !ignoreMapNull>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.clear();
|
||||
</#if>
|
||||
<@lib.handleLocalVarNullCheck needs_explicit_local_var=false>
|
||||
<#if ext.existingInstanceMapping && ignoreMapNull>
|
||||
${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>
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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._3806;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
public interface Issue3806Mapper {
|
||||
|
||||
Issue3806Mapper INSTANCE = Mappers.getMapper( Issue3806Mapper.class );
|
||||
|
||||
void update(@MappingTarget Target target, Target source);
|
||||
|
||||
class Target {
|
||||
|
||||
private final Collection<String> authors;
|
||||
private final Map<String, String> booksByAuthor;
|
||||
|
||||
protected Collection<String> books;
|
||||
protected Map<String, String> booksByPublisher;
|
||||
|
||||
public Target(Collection<String> authors, Map<String, String> booksByAuthor) {
|
||||
this.authors = authors != null ? new ArrayList<>( authors ) : null;
|
||||
this.booksByAuthor = booksByAuthor != null ? new HashMap<>( booksByAuthor ) : null;
|
||||
}
|
||||
|
||||
public Collection<String> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public Map<String, String> getBooksByAuthor() {
|
||||
return booksByAuthor;
|
||||
}
|
||||
|
||||
public Collection<String> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(Collection<String> books) {
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
public Map<String, String> getBooksByPublisher() {
|
||||
return booksByPublisher;
|
||||
}
|
||||
|
||||
public void setBooksByPublisher(Map<String, String> booksByPublisher) {
|
||||
this.booksByPublisher = booksByPublisher;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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._3806;
|
||||
|
||||
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;
|
||||
|
||||
@WithClasses(Issue3806Mapper.class)
|
||||
@IssueKey("3806")
|
||||
class Issue3806Test {
|
||||
|
||||
@ProcessorTest
|
||||
void shouldNotClearGetterOnlyCollectionsInUpdateMapping() {
|
||||
Map<String, String> booksByAuthor = new HashMap<>();
|
||||
booksByAuthor.put( "author1", "book1" );
|
||||
booksByAuthor.put( "author2", "book2" );
|
||||
List<String> authors = new ArrayList<>();
|
||||
authors.add( "author1" );
|
||||
authors.add( "author2" );
|
||||
|
||||
List<String> books = new ArrayList<>();
|
||||
books.add( "book1" );
|
||||
books.add( "book2" );
|
||||
Map<String, String> booksByPublisher = new HashMap<>();
|
||||
booksByPublisher.put( "publisher1", "book1" );
|
||||
booksByPublisher.put( "publisher2", "book2" );
|
||||
Issue3806Mapper.Target target = new Issue3806Mapper.Target( authors, booksByAuthor );
|
||||
target.setBooks( books );
|
||||
target.setBooksByPublisher( booksByPublisher );
|
||||
|
||||
Issue3806Mapper.Target source = new Issue3806Mapper.Target( null, null );
|
||||
Issue3806Mapper.INSTANCE.update( target, source );
|
||||
|
||||
assertThat( target.getAuthors() ).containsExactly( "author1", "author2" );
|
||||
assertThat( target.getBooksByAuthor() )
|
||||
.containsOnly(
|
||||
entry( "author1", "book1" ),
|
||||
entry( "author2", "book2" )
|
||||
);
|
||||
|
||||
assertThat( target.getBooks() ).containsExactly( "book1", "book2" );
|
||||
assertThat( target.getBooksByPublisher() )
|
||||
.containsOnly(
|
||||
entry( "publisher1", "book1" ),
|
||||
entry( "publisher2", "book2" )
|
||||
);
|
||||
|
||||
booksByAuthor = new HashMap<>();
|
||||
booksByAuthor.put( "author3", "book3" );
|
||||
authors = new ArrayList<>();
|
||||
authors.add( "author3" );
|
||||
|
||||
books = new ArrayList<>();
|
||||
books.add( "book3" );
|
||||
booksByPublisher = new HashMap<>();
|
||||
booksByPublisher.put( "publisher3", "book3" );
|
||||
source = new Issue3806Mapper.Target( authors, booksByAuthor );
|
||||
source.setBooks( books );
|
||||
source.setBooksByPublisher( booksByPublisher );
|
||||
Issue3806Mapper.INSTANCE.update( target, source );
|
||||
|
||||
assertThat( target.getAuthors() ).containsExactly( "author3" );
|
||||
assertThat( target.getBooksByAuthor() )
|
||||
.containsOnly(
|
||||
entry( "author3", "book3" )
|
||||
);
|
||||
|
||||
assertThat( target.getBooks() ).containsExactly( "book3" );
|
||||
assertThat( target.getBooksByPublisher() )
|
||||
.containsOnly(
|
||||
entry( "publisher3", "book3" )
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user