我有一个包含一个集合的对象:
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_
发布于 2014-04-24 04:36:20
您必须给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>
发布于 2014-04-23 18:40:25
一个解决方案可以是创建一个自定义DozerConverter。在转换器方法中,可以在运行时检查具体实例类型。
https://stackoverflow.com/questions/23248973
复制相似问题