Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CollectionMappingStrategy with option not to clean target collection prior to adding all elements #3538

Open
typekpb opened this issue Feb 23, 2024 · 2 comments

Comments

@typekpb
Copy link

typekpb commented Feb 23, 2024

Use case

Having map in a mapping target, I want to have option to keep it's existing elements, just call putAll() on addiing new ones (or replacing existing with the same key)

class Test {
Map<String,String> customFields;
}

@Mapper
TestMapper {

  @Mapping(target = "customFields", source = "customFields)
  Test update(Test source, @MappingTarget Test target);
}

Generated Code

if ( target.getCustomFields() != null ) {
            Map<String, String> map = source.getCustomFields();
            if ( map != null ) {
                // the following line would not be present
                // target.getCustomFields().clear();
                target.getCustomFields().putAll( map );
            }
            else {
                target.setCustomFields( new java.util.HashMap<>() );
            }
        }

Possible workarounds

custom mapping implementation needed

MapStruct Version

1.5.5.Final

@filiphr
Copy link
Member

filiphr commented Feb 25, 2024

@typekpb have you perhaps tried using an adder and CollectionMappingStrategy#ADDER_PREFERRED? I am not sure if we are clearing the collection in this case.

@aprevost
Copy link

aprevost commented Jul 4, 2024

@typekpb have you perhaps tried using an adder and CollectionMappingStrategy#ADDER_PREFERRED? I am not sure if we are clearing the collection in this case.

I also have a need for this feature... or at least, something similar. In my case, it's a bit simpler, where both the source and the target have a property that is a List, and I want to just add any values in the source list proprety to any pre-existing values in the target list property.

I don't own the target model so can't easily add an "add" method to it as you suggest. We just really need a way to modify the current generated code:

        if ( target.getListProperty() != null ) {
            target.getListProperty.clear();
            List<String> list = source.getListProperty();
            if ( list != null ) {
                target.getListProperty().addAll( list );
            }
        }

so that, it doesn't do the clear first:

       if ( target.getListProperty() != null ) {
            List<String> list = source.getListProperty();
            if ( list != null ) {
                target.getListProperty().addAll( list );
            }
        }

AND also handles the case where the target list is null but the sourceList is not null:

       else { //target.getListProperty() == null
            List<String> list = source.getListProperty();
            if ( list != null ) {
                target.setListProperty(new ArrayList<>(list));
            }
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants