modelmapper / modelmapper

Intelligent object mapping
http://modelmapper.org
Apache License 2.0
2.29k stars 349 forks source link

Not map correct when property is List #584

Open jamestao83 opened 3 years ago

jamestao83 commented 3 years ago
public class Demo {
    private List<Long> ids
}

Demo demo1 = new Demo()
    .setIds(Lists.newArrayList(3L));
Demo demo2 = new Demo()
    .setIds(Lists.newArrayList(1L, 2L, 3L));
ModelMapper mapper = new ModelMapper();
mapper.map(demo1, demo2);

After map, I hope the demo2 ids value is 3L, but it still is 1L, 2L, 3L

chhsiao90 commented 3 years ago

I guessed you are looking for setCollectionsMergeEnabled.

It's enabled by default, you can disable that the collection of destination was always replaced from the source collection.

seidhkona commented 3 years ago

I know it's an old question, but saw it's still open. I'm new to ModelMapper and I'm using setCollectionMergeEnabled(false) with latest ModelMapper (2.4.4), but it doesn't work. Here is code example:

var foo1 = new Foo();
var test1 = new HashMap<String, String>();
test1.put("key", "val");
foo1.setConfigData(test1);
var foo2= new Foo();
var test2 = new HashMap<String, String>();
test2.put("key1", "val1");
test2.put("key2", "val2");
foo2.setConfigData(test2);
modelMapper.map(foo1,foo2);

I'm expecting that foo2 will have configData with 1 element in it, but it ends up having 3 (merged from test1 and test2)

also, inspecting config of ModelMapper shows that collectionMergeEnabled=true even though I set it to false. I looked through the code and I don't see that property being updated anywhere.. I don't think it's used anywhere, since the real usage is to replace CollectionConverter with NonMergingCollectionConverter (which doesn't work?), but it's confusing still...

hoangntv-1399 commented 1 year ago

The reason why the actual result is different from the expected result is because ModelMapper maps fields by name, not by type. In this case, both demo1 and demo2 have a field named ids, so ModelMapper will map the value of demo1.ids to demo2.ids, regardless of the fact that demo1.ids is a list of a single element, while demo2.ids is a list of three elements.

ModelMapper mapper = new ModelMapper();
mapper.addMappings(new PropertyMap<Demo, Demo>() {
    @Override
    protected void configure() {
        map(source.getIds(), destination.getIds(), mapIds);
    }
});

mapper.map(demo1, demo2);