我有一个包含Collection的对象:
public class Wrapper {
private Collection<Base> bases = new LinkedList<Base>();
public Collection<Base> getBases() {return bases;}
public void setBases(final Collection<Base> bases) {this.bases = bases;}
}
界面的实现非常简单:
public class BaseOne implements Base {
}
public class BaseTwo implements Base {
}
当我进行简单测试时:
@Test
public void testCopyOther() {
final Wrapper wrapper = new Wrapper();
wrapper.getBases().add(new BaseOne());
final Wrapper copy = dozer.map(wrapper, Wrapper.class);
}
我得到了这个例外:
org.dozer.MappingException: java.lang.NoSuchMethodException: com.usamp.biddingtool.model.service.impl.Base.<init>()
at org.dozer.util.MappingUtils.throwMappingException(MappingUtils.java:82)
at org.dozer.factory.ConstructionStrategies$ByConstructor.newInstance(ConstructionStrategies.java:261)
at org.dozer.factory.ConstructionStrategies$ByConstructor.create(ConstructionStrategies.java:245)
at org.dozer.factory.DestBeanCreator.create(DestBeanCreator.java:65)
at org.dozer.MappingProcessor.mapCustomObject(MappingProcessor.java:489)
at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:446)
at org.dozer.MappingProcessor.addOrUpdateToList(MappingProcessor.java:776)
at org.dozer.MappingProcessor.addOrUpdateToList(MappingProcessor.java:850)
at org.dozer.MappingProcessor.mapListToList(MappingProcessor.java:686)
at org.dozer.MappingProcessor.mapCollection(MappingProcessor.java:541)
at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:434)
at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:342)
at org.dozer.MappingProcessor.mapField(MappingProcessor.java:288)
at org.dozer.MappingProcessor.map(MappingProcessor.java:248)
at org.dozer.MappingProcessor.map(MappingProcessor.java:197)
at org.dozer.MappingProcessor.map(MappingProcessor.java:187)
at org.dozer.MappingProcessor.map(MappingProcessor.java:124)
at org.dozer.MappingProcessor.map(MappingProcessor.java:119)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:120)
at com.usamp.biddingtool.model.service.impl.DozerTest.testCopyOther(DozerTest.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
因此,似乎Dozer正在尝试创建集合中使用的实际类型的实例,而类型只是一个接口。由于无法实例化接口,因此会产生错误。
我见过其他人问过这个问题,但并没有真正得到任何具体答案。这个问题有什么解决方案吗?
感谢。 -AP_
答案 0 :(得分:2)
您必须向Dozer提供有关Base实施的提示。否则它将尝试实例化接口,这是不可能的。
<mapping>
<class-a>Wrapper</class-a>
<class-b>Wrapper</class-b>
<field>
<a>bases</a>
<b>bases</b>
<a-hint>BaseOne,BaseTwo</a-hint>
<b-hint>BaseOne,BaseTwo</b-hint>
</field>
</mapping>
http://dozer.sourceforge.net/documentation/baseattributes.html
替代(更新):
<mapping>
<class-a>BaseOne</class-a>
<class-b>BaseOne</class-b>
</mapping>
<mapping>
<class-a>BaseTwo</class-a>
<class-b>BaseTwo</class-b>
</mapping>
答案 1 :(得分:0)
一种解决方案可以是创建custom DozerConverter。在转换器方法中,您可以在运行时检查具体实例类型。