Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ModelMapper: how to map java.util.Map to POJO?

How can I map a java.util.Map to a POJO?

The following test gives me a configuration error.

It seems a similar issue was opened but it was not resolved https://github.com/jhalterman/modelmapper/issues/116.

Test:

package org.me.modelmapper;

import java.util.HashMap;
import org.modelmapper.ModelMapper;
import org.modelmapper.PropertyMap;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class MapperTest {


    private ModelMapper modelMapper;


    public MapperTest() {
    }


    public static class Foo {

        public String a;
        public String b;

        public String getA() {
            return a;
        }

        public void setA(String a) {
            this.a = a;
        }

        public String getB() {
            return b;
        }

        public void setB(String b) {
            this.b = b;
        }

    }


    @BeforeMethod
    public void setUpMethod() throws Exception {
        modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setFieldMatchingEnabled(true);
    }

    @Test
    public void shouldMapHashMapToFoo() {
        HashMap<String, String> map = new HashMap<>();
        map.put("a", "aaaa");
        map.put("b", "bbbb");

        PropertyMap<HashMap<String, String>, Foo> fooMap = new PropertyMap<HashMap<String, String>, MapperTest.Foo>() {

            @Override
            protected void configure() {
                map(source.get("a"), destination.a);
                map(source.get("b"), destination.b);
            }

        };

        modelMapper.addMappings(fooMap);

        Foo foo = modelMapper.map(map, Foo.class);

        Assert.assertEquals(foo.getA(), map.get("a"));
        Assert.assertEquals(foo.getB(), map.get("b"));

    }

}

Error:

Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator@60acc399
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 2.326 sec <<< FAILURE!
shouldMapHashMapToFoo(org.me.modelmapper.MapperTest)  Time elapsed: 0.186 sec  <<< FAILURE!
org.modelmapper.ConfigurationException: ModelMapper configuration errors:

1) Invalid source method java.util.HashMap.get(). Ensure that method has zero parameters and does not return void.

2) Invalid source method java.util.HashMap.get(). Ensure that method has zero parameters and does not return void.

2 errors
    at org.modelmapper.internal.Errors.throwConfigurationExceptionIfErrorsExist(Errors.java:241)
    at org.modelmapper.internal.ExplicitMappingBuilder.visitPropertyMap(ExplicitMappingBuilder.java:228)
    at org.modelmapper.PropertyMap.configure(PropertyMap.java:380)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.modelmapper.internal.ExplicitMappingBuilder.build(ExplicitMappingBuilder.java:194)
    at org.modelmapper.internal.TypeMapImpl.addMappings(TypeMapImpl.java:72)
    at org.modelmapper.internal.TypeMapStore.getOrCreate(TypeMapStore.java:101)
    at org.modelmapper.ModelMapper.addMappings(ModelMapper.java:93)
    at org.me.modelmapper.MapperTest.shouldMapHashMapToFoo(MapperTest.java:354)


Results :

Failed tests:   shouldMapHashMapToFoo(org.me.modelmapper.MapperTest): ModelMapper configuration errors:
(..)

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
like image 284
dmz73 Avatar asked Jan 19 '26 14:01

dmz73


1 Answers

It is mapped automatically. You do not need to configure any mapping. This will work:

@Test
public void shouldMapHashMapToFoo() {
    HashMap<String, String> map = new HashMap<>();
    map.put("a", "aaaa");
    map.put("b", "bbbb");

    Foo foo = modelMapper.map(map, Foo.class);

    Assert.assertEquals(foo.getA(), map.get("a"));
    Assert.assertEquals(foo.getB(), map.get("b"));

}

EDIT: If you need to map HashMap to more complicated structure, you can always use "intermediate" class.

  public static class Bar
  {
    private String Z;
    private String W;

    public String getZ()
    {
      return Z;
    }

    public void setZ(String z)
    {
      Z = z;
    }

    public String getW()
    {
      return W;
    }

    public void setW(String w)
    {
      W = w;
    }
  }

  @Test
  public void shouldMapHashMapToFoo()
  {
    HashMap<String, String> map = new HashMap<>();
    map.put("z", "aaaa");
    map.put("w", "bbbb");

    Bar bar = modelMapper.map(map, Bar.class);

    PropertyMap<Bar, Foo> barToFooMap = new PropertyMap<Bar, Foo>()
    {
      @Override
      protected void configure()
      {
        map().setA(source.getZ());
        map().setB(source.getW());
      }

    };
    modelMapper.addMappings(barToFooMap);

    Foo foo = modelMapper.map(bar, Foo.class);

    Assert.assertEquals(foo.getA(), map.get("z"));
    Assert.assertEquals(foo.getB(), map.get("w"));
  }
like image 108
bigGuy Avatar answered Jan 21 '26 02:01

bigGuy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!