测试DAO时出错:sun.reflect.generics.reflectiveObjects.TypeVariableImpl无法强制转换为java.lang.Class

我是Spring + Hibernate的新手,我正在运行测试,看看我的DAO是否正常工作。 我收到以下错误,在Google上搜索会产生很多不同的答案(主要是拼写错误,我已经检查过)。 我希望你能帮我解决这个问题:

java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) at org.junit.runner.JUnitCore.run(JUnitCore.java:157) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nominationDao' defined in file [C:\IdeaProjects\Projects\branch\dev\test-dataacess\target\classes\com\dev\test\data\dao\hibernate\NominationHibernateDAO.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.dev.test.data.dao.hibernate.NominationHibernateDAO]: Constructor threw exception; nested exception is java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:900) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:455) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1) at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280) at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304) ... 27 more Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.dev.test.data.dao.hibernate.NominationHibernateDAO]: Constructor threw exception; nested exception is java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:108) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280) ... 42 more Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class at com.dev.test.data.dao.hibernate.AbstractHibernateDAO.(AbstractHibernateDAO.java:50) at com.dev.test.data.dao.hibernate.NominationHibernateDAO.(NominationHibernateDAO.java:36) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147) ... 44 more 

什么可能导致这个? 如果我在AbstractHibernateDAO和NominationHibernateDAO中编辑,请告诉我。

谢谢!

这里编辑的是片段:

这是AbstractHibernateDAO的片段,第50行是注释:

 public abstract class AbstractHibernateDAO implements DAO { protected Logger logger = LoggerFactory.getLogger(this.getClass()); private SessionFactory sessionFactory; private Class persistentClass; protected AbstractHibernateDAO(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; this.persistentClass = (Class) ((ParameterizedType) //LINE 50 getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } 

第36行之后是对NominationHibernateDAO的这个片段的评论:

 @Repository("nominationDao") public class NominationHibernateDAO extends AbstractHibernateDAO implements NominationDAO { @Autowired(required = true) public NominationHibernateDAO(SessionFactory sessionFactory) { super(sessionFactory); //LINE 36 } 

表达方式

 getClass().getGenericSuperclass()).getActualTypeArguments()[0] 

指的是替换为AbstractHibernateDAO第一个类型参数的值(在AbstractHibernateDAO.java中用T表示)。 子类NominationHibernateDAO替换的类型仍然不具体,它是T extends Nomination ,它绝对不是java.lang.Class实例,而是Type实例( TypeVariableImplType的实现)。

如果使用类似的东西声明NominationHibernateDAO

 class NominationHibernateDAO extends AbstractHibernateDAO { ... 

然后AbstractHibernateDAO构造函数魔术会起作用。 或者,您可以(或者您应该?)实例化NominationHibernateDAO的子类,如下所示:

 class ConcreteNominationHibernateDAO extends NominationHibernateDAO { ... 

要么

 new NominationHibernateDAO() {} 

这再次不会引发问题。

你确定NominationHibernateDAO类是用作Spring bean吗?