我在ModelMapper 0.7.5上测试过。
如果模型具有以下条件,则ModelMapper无法映射它们。
测试代码是
public static class SomeModelMapper extends ModelMapper {
public void init() {
getConfiguration().setMatchingStrategy(MatchingStrategies.STANDARD);
}
}
@Data
public static class Dto1 {
private Dto1 another;
private String anothorPath;
}
@Data
public static class Dto2 {
private Dto2 parent;
private String parentPath;
}
@Test
public void testMapping() {
SomeModelMapper mapper = new SomeModelMapper();
mapper.init();
Map map = new HashMap<>();
map.put("anothorPath", "x");
Dto1 dto1 = mapper.map(map, Dto1.class);
assertThat(dto1.getAnothorPath(), is("x")); // success
map.clear();
map.put("parentPath", "y");
Dto2 dto2 = mapper.map(map, Dto2.class); // failed
assertThat(dto2.getParentPath(), is("y"));
}
错误消息是
org.modelmapper.MappingException: ModelMapper mapping errors:
1) Error mapping java.util.HashMap to com.semogyo.api.web.mapper.Object2ObjectMapperTest$Dto2
1 error
at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:374)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:69)
at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:497)
at org.modelmapper.ModelMapper.map(ModelMapper.java:340)
at com.semogyo.api.web.mapper.Object2ObjectMapperTest.testMapping(Object2ObjectMapperTest.java:202)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.modelmapper.MappingException: ModelMapper mapping errors:
1) Failed to set value 'Object2ObjectMapperTest.Dto2(parent=null, parentPath=null)' on com.semogyo.api.web.mapper.Object2ObjectMapperTest$Dto2.setParentPath()
1 error
at org.modelmapper.internal.Errors.toMappingException(Errors.java:258)
at org.modelmapper.internal.PropertyInfoImpl$MethodMutator.setValue(PropertyInfoImpl.java:118)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:249)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:180)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:131)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:101)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:60)
... 30 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.modelmapper.internal.PropertyInfoImpl$MethodMutator.setValue(PropertyInfoImpl.java:116)
... 35 more
为什么我不能使用方法名称的“父”?
答案 0 :(得分:1)
您可以使用&#34; parent&#34;如你所愿,但不是在这种情况下。如果您更改了您的房产名称&#34; parent&#34;对其他令牌它起作用(例如&#34;父亲&#34;)。但是尝试改变你的另一个例子Dto1,看看会发生什么:(属性&#34; anothor&#34;到#34;另一个&#34;):
@Data
public static class Dto1 {
private Dto1 another;
private String anotherPath;
}
你的HashMap(anothorPath - &gt; anotherPath):
Map<String, String> map = new HashMap<>();
map.put("anotherPath", "x");
Dto1 dto1 = mapper.map(map, Dto1.class);
它发生了同样的错误:
Caused by: org.modelmapper.MappingException: ModelMapper mapping errors:
1) Failed to set value 'Test.Dto1(another=null, anotherPath=null)' on com.example.Test$Dto1.setAnotherPath()
... same trace error
为什么呢?简单地说,就像你的样本一样,它会产生一个无限循环。
让我解释一下原因。 ModelMapper查找String parentPath
访问器并且它是可映射的,然后它会尝试映射Dto2 parent
等等...如果您将另一个名称添加到Dto2
,它不会尝试映射{ {1}}并且不会生成循环。
想象一下你的课程是这样的:
Dto2
输出为@Data
public static class Dto1 {
private Dto2 another;
private String parentPath;
}
@Data
public static class Dto2 {
private Dto1 parent;
private String parentPath;
}
。它会映射Test.Dto2(parent=Test.Dto1(another=null, parentPath=y), parentPath=y)
Dto1和Dto2。
但是如果您的课程与下一课一样:
String parent
再次产生错误,同样是无限循环。
这种映射不受支持也许作者认为这样做更好是一致的,我不知道。