ModelMapper无法映射名为“父”的方法

时间:2016-06-04 17:21:59

标签: mapping parent modelmapper

我在ModelMapper 0.7.5上测试过。

如果模型具有以下条件,则ModelMapper无法映射它们。

  • 方法名称为'parent'并返回自我类
  • 方法名称为'parentPath'并返回字符串

测试代码是

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

为什么我不能使用方法名称的“父”?

1 个答案:

答案 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

为什么呢?简单地说,就像你的样本一样,它会产生一个无限循环。

  1. ModelMapper映射String parentPath
  2. ModelMapper映射DTO2 parent - &gt; String ParentPath。
  3. ModelMapper映射DTO2 parent - &gt; DTO2父母 - &gt;字符串parentPath
  4. ModelMapper映射DTO2 parent - &gt; DTO2父母 - &gt; DTO2父母 - &gt;字符串parentPath
  5. ....无限循环....这似乎不会停止......
  6. 让我解释一下原因。 ModelMapper查找String parentPath访问器并且它是可映射的,然后它会尝试映射Dto2 parent等等...如果您将另一个名称添加到Dto2,它不会尝试映射{ {1}}并且不会生成循环。

    实施例

    案例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。

    案例2

    但是如果您的课程与下一课一样:

    String parent

    再次产生错误,同样是无限循环。

    结论

    这种映射不受支持也许作者认为这样做更好是一致的,我不知道。