ModelMapper将LinkedHashMap转换为LinkedHashMap时出现ArrayIndexOutOfBoundsException错误。

huangapple go评论76阅读模式
英文:

ModelMapper LinkedHashMap to LinkedHashMap ArrayIndexOutOfBoundsException

问题

以下是您要翻译的内容:

"I've been working on a project where some new status data is fetched into an object and applied via ModelMapper on the current object status data.
Fields are matched and updated automatically which is nice.

Now I've added some more complex data in the form of a List<Map<String, String>>.
And things are breaking.

Here is the simplified code :

public class TypeA {     
   private List<Map<String, String>> listOfMap;
  
}

public class TypeB {     
   private List<Map<String, String>> listOfMap;
  
}

public class Test {
   public static void main(String[] args) {           
		TypeA typeA = new TypeA();		
		TypeB typeB = new TypeB();
		
		Map<String, String> m1 = new LinkedHashMap<>();
		m1.put("test1", "machin");
		m1.put("test2", "truc");
		m1.put("test3", "bidule");
		
		Map<String, String> m2 = new LinkedHashMap<>();
		m2.put("test1", "machin");
		m2.put("test2", "truc");
		
		List<Map<String, String>> l1 = new ArrayList<>();		
		l1.add(m1);
		
		List<Map<String, String>> l2 = new ArrayList<>();		
		l2.add(m2);
		
		typeA.setListOfMap(l1);		
		typeB.setListOfMap(l2);	  // this can be set to null to fix the problem  
		
		ModelMapper modelmapper = new ModelMapper();
        
         try {
                modelmapper.map(typeA, typeB); 
         } catch (Exception e) {
                e.printStackTrace();
         }
   }
}

Things are working alright if typeB listOfMap is Empty.
But if we already have another list of values in listOfMap on object typeB.
Then we get the following error when trying to map A to B :

 
1) Converter org.modelmapper.internal.converter.MapConverter@1f32e575 failed to convert java.util.LinkedHashMap to java.util.LinkedHashMap.
 
1 error
   at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:380)
   at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:81)
   at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:573)
   at org.modelmapper.ModelMapper.map(ModelMapper.java:447)
   at modelmapper_debug.Main.main(Main.java:30)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
   at org.modelmapper.internal.converter.MapConverter.convert(MapConverter.java:59)
   at org.modelmapper.internal.converter.MapConverter.convert(MapConverter.java:1)
   at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
   at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
   at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
   at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:1)
   at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
   at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
   at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
   at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
   at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
   at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:115)
   at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:72)
   ... 3 more

What is happening here?
Can I fix this code to make ModelMapper map List<Map<String, String>> type correctly ?

thx all"

英文:

I've been working on a project where some new status data is fetched into an object and applied via ModelMapper on the current object status data.
Fields are matched and updated automatically which is nice.

Now I've added some more complex data in the form of a List<Map<String, String>>.
And things are breaking.

Here is the simplified code :

public class TypeA {     
private List&lt;Map&lt;String, String&gt;&gt; listOfMap;
}
public class TypeB {     
private List&lt;Map&lt;String, String&gt;&gt; listOfMap;
}
public class Test {
public static void main(String[] args) {           
TypeA typeA = new TypeA();		
TypeB typeB = new TypeB();
Map&lt;String, String&gt;  m1 = new LinkedHashMap();
m1.put(&quot;test1&quot;,&quot;machin&quot;);
m1.put(&quot;test2&quot;,&quot;truc&quot;);
m1.put(&quot;test3&quot;,&quot;bidule&quot;);
Map&lt;String, String&gt;  m2 = new LinkedHashMap();
m2.put(&quot;test1&quot;,&quot;machin&quot;);
m2.put(&quot;test2&quot;,&quot;truc&quot;);
List&lt;Map&lt;String, String&gt;&gt; l1 = new ArrayList&lt;Map&lt;String, String&gt;&gt;();		
l1.add(m1);
List&lt;Map&lt;String, String&gt;&gt; l2 = new ArrayList&lt;Map&lt;String, String&gt;&gt;();		
l2.add(m2);
typeA.setListOfMap(l1);		
typeB.setListOfMap(l2);	  // this can be set to null to fix the problem  
ModelMapper modelmapper = new ModelMapper();
try {
modelmapper.map(typeA, typeB); 
} catch (Exception e) {
e.printStackTrace();
}
}
}

Things are working alright if typeB listOfMap is Empty.
But if we already have another list of values in listOfMap on object typeB.
Then we get the following error when trying to map A to B :

 
1) Converter org.modelmapper.internal.converter.MapConverter@1f32e575 failed to convert java.util.LinkedHashMap to java.util.LinkedHashMap.
1 error
at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:380)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:81)
at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:573)
at org.modelmapper.ModelMapper.map(ModelMapper.java:447)
at modelmapper_debug.Main.main(Main.java:30)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at org.modelmapper.internal.converter.MapConverter.convert(MapConverter.java:59)
at org.modelmapper.internal.converter.MapConverter.convert(MapConverter.java:1)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:1)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:115)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:72)
... 3 more

What is happening here?
Can I fix this code to make ModelMapper map List<Map<String, String>> type correctly ?

thx all

答案1

得分: 0

  1. 我不知道为什么您要使用 modelmapper.map(typeA, typeB) 而不是 modelmapper.map(typeA, TypeB.class) 链接

  2. 您可以为复杂数据使用自定义映射:

public class TestModelMapper extends ModelMapper {

    TestModelMapper() {
        super();
        this.initMappings();
    }

    private void initMappings() {
        Converter<List<Map<String, String>>, List<Map<String, String>>> converter = new Converter<>() {
            public List<Map<String, String>> convert(MappingContext<List<Map<String, String>>, List<Map<String, String>>> context) {
                return context.getSource() == null ? null : new ArrayList<>(context.getSource());
            }
        };
        PropertyMap<TypeA, TypeB> entityToDTOMap = new PropertyMap<>() {
            protected void configure() {
                using(converter).map(source.getListOfMap()).setListOfMap(null);
            }
        };

        this.addMappings(entityToDTOMap);
    }
}

public class Test {

    public static void main(String[] args) {
        TypeA typeA = new TypeA();
        TypeB typeB = new TypeB();

        Map<String, String> m1 = new LinkedHashMap();
        m1.put("test1", "machin");
        m1.put("test2", "truc");
        m1.put("test3", "bidule");

        List<Map<String, String>> l1 = new ArrayList<Map<String, String>>();
        l1.add(m1);

        typeA.setListOfMap(l1);

        ModelMapper modelmapper = new TestModelMapper();

        try {
            modelmapper.map(typeA, TypeB.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
英文:
  1. I don't know why you use modelmapper.map(typeA, typeB) instead of modelmapper.map(typeA, TypeB.class) http://modelmapper.org/getting-started/
  2. You can use your own mappings for complex data:

<pre>
public class TestModelMapper extends ModelMapper {

TestModelMapper() {
super();
this.initMappings();
}
private void initMappings() {
Converter&lt;List&lt;Map&lt;String, String&gt;&gt;, List&lt;Map&lt;String, String&gt;&gt;&gt; converter = new Converter&lt;&gt;() {
public List&lt;Map&lt;String, String&gt;&gt; convert(MappingContext&lt;List&lt;Map&lt;String, String&gt;&gt;, List&lt;Map&lt;String, String&gt;&gt;&gt; context) {
return context.getSource() == null ? null : new ArrayList&lt;&gt;(context.getSource());
}
};
PropertyMap&lt;TypeA, TypeB&gt; entityToDTOMap = new PropertyMap&lt;&gt;() {
protected void configure() {
using(converter).map(source.getListOfMap()).setListOfMap(null);
}
};
this.addMappings(entityToDTOMap);
}

}

public class Test {

public static void main(String[] args) {           
TypeA typeA = new TypeA();      
TypeB typeB = new TypeB();
Map&lt;String, String&gt;  m1 = new LinkedHashMap();
m1.put(&quot;test1&quot;,&quot;machin&quot;);
m1.put(&quot;test2&quot;,&quot;truc&quot;);
m1.put(&quot;test3&quot;,&quot;bidule&quot;);
List&lt;Map&lt;String, String&gt;&gt; l1 = new ArrayList&lt;Map&lt;String, String&gt;&gt;();        
l1.add(m1);
typeA.setListOfMap(l1);     
ModelMapper modelmapper = new TestModelMapper();
try {
modelmapper.map(typeA, TypeB.class); 
} catch (Exception e) {
e.printStackTrace();
}
}

}
</pre>

答案2

得分: 0

在当时,我正在运行此代码,使用了modelmapper依赖版本2.3.8。升级到最新版本2.4.2 可以解决这个问题。

ModelMapper modelmapper = new ModelMapper();

try {
    System.out.println(typeB.getListOfMap().toString());
    modelmapper.map(typeA, typeB); 
    System.out.println(typeB.getListOfMap().toString());
} catch (Exception e) {
    e.printStackTrace();
}

预期输出:

[{test1=machin, test2=truc}]  
[{test1=machin, test2=truc, test3=bidule}]
英文:

At the time, I was running this code with modelmapper dependency version 2.3.8.
Updating to the latest release 2.4.2 fixes this problem.

    ModelMapper modelmapper = new ModelMapper();
try {
System.out.println(typeB.getListOfMap().toString());
modelmapper.map(typeA, typeB); 
System.out.println(typeB.getListOfMap().toString());
} catch (Exception e) {
e.printStackTrace();
}

Ouputs as expected :

[{test1=machin, test2=truc}]  
[{test1=machin, test2=truc, test3=bidule}]

huangapple
  • 本文由 发表于 2020年8月6日 03:28:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63272283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定