[英]java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
I am stuck with this issue for a long time. 我长期坚持这个问题。 I searched for this issue for sometime but none of solution worked. 我曾经搜索过这个问题,但没有一个解决方案有效。
Structure: 结构体:
public interface GenericDAO<T extends Serializable, ID extends Serializable>
@Repository
public class AbstractGenericDAO<T extends Serializable, ID extends Serializable>
implements GenericDAO<T, ID> {
private Class<T> persistentClass;
@Autowired
private SessionFactory sessionFactory;
static Logger LOGGER = Logger.getLogger(AbstractGenericDAO.class);
@SuppressWarnings("unchecked")
public AbstractGenericDAO() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
/**
* @param entity
* @return T
* @throws DBException
*/
@SuppressWarnings("unchecked")
public T saveEntity(T entity) throws DBException {
return saveEntity(entity, false);
}
/**
* @param entity
* @param explicitFlush
* @return T
* @throws DBException
*/
@SuppressWarnings("unchecked")
public T saveEntity(T entity, boolean explicitFlush) throws DBException {
Session session = getSessionFactory().getCurrentSession();
try {
session.save(entity);
if(explicitFlush) {
session.flush();
session.refresh(entity);
}
} catch (HibernateException he) {
String errorMsg = "Could not save entity. Reason: " + he.getMessage();
LOGGER.error(errorMsg, he);
throw new DBException(errorMsg, he);
}
return entity;
}
/* (non-Javadoc)
* @see com.amazon.fc.receive.dbaccess.dao.GenericDAO#getPersistentClass()
*/
@SuppressWarnings("unchecked")
public Class<T> getPersistentClass() {
return persistentClass;
}
/**
* @return the sessionFactory
*/
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
/**
* @param sessionFactory the sessionFactory to set
*/
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
public interface ShlkActiveWorkflowDAO
extends GenericDAO<ShlkActiveWorkflow, Serializable>
@Repository
public class ShlkActiveWorkflowDAOImpl
extends AbstractGenericDAO<ShlkActiveWorkflow, Serializable>
implements ShlkActiveWorkflowDAO
I am also using <context:component-scan>
in my application-config.xml
+ <tx:annotation-driven />
in my application-config.xml
. 我也使用<context:component-scan>
在我的application-config.xml
+ <tx:annotation-driven />
在我的application-config.xml
。
Please provide some information about how to fix this issue. 请提供有关如何解决此问题的一些信息。
Exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'abstractGenericDAO'
Constructor threw exception; nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:946)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:890)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
at com.coral.spring.Launcher.<init>(Launcher.java:95)
at com.coral.spring.Launcher.main(Launcher.java:56)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.workflow.dao.AbstractGenericDAO]: Constructor threw exception; nested exception is
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:72)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:938)
... 12 more
Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at com.workflow.dao.AbstractGenericDAO.<init>(AbstractGenericDAO.java:43)
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:126)
... 14 more
Remove @Repository
annotation from AbstractGenericDAO
and make it abstract
: 从AbstractGenericDAO
删除@Repository
注释并使其成为abstract
:
public abstract class AbstractGenericDAO<T extends Serializable, ID extends Serializable>
implements GenericDAO<T, ID>
Your problem occurs because @Repository
is a specialization of @Component
, which means that Spring will try to create AbstractGenericDAO
instances for injection. 出现问题是因为@Repository
是@Component
,这意味着Spring将尝试创建用于注入的AbstractGenericDAO
实例。 Since AbstractGenericDAO
superclass ( Object
) is not generic, you will not be able to downcast its Type
to ParameterizedType
, and so this line of code will fail (in the same way that it would if you tried to instantiate it manually with new AbstractGenericDAO()
): 由于AbstractGenericDAO
超类( Object
)不是通用的,因此您无法将其Type
转发为ParameterizedType
,因此这行代码将失败(与您尝试使用new AbstractGenericDAO()
手动实例化它时的方式相同):
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
The specialized class ShlkActiveWorkflowDAOImpl
should still be annotated with @Repository
. 专业类ShlkActiveWorkflowDAOImpl
仍应予以注释@Repository
。 When spring tries to create a instance of this class a implicit call to AbstractGenericDAO
constructor will occur, but this time the line of code mentioned above will run as expected. 当spring尝试创建此类的实例时,将发生对AbstractGenericDAO
构造函数的隐式调用,但这次上面提到的代码行将按预期运行。 This happens because getClass()
returns ShlkActiveWorkflowDAOImpl.class
which is a subclass of the generic AbstractGenericDAO
(so the downcast to ParameterizedType
works). 发生这种情况是因为getClass()
返回ShlkActiveWorkflowDAOImpl.class
,它是泛型AbstractGenericDAO
的子类(因此向下转换为ParameterizedType
有效)。
Since ShlkActiveWorkflowDAOImpl
extends
AbstractGenericDAO<ShlkActiveWorkflow, Serializable>
the actual type ShlkActiveWorkflow
will be correctly reflected at runtime. 由于ShlkActiveWorkflowDAOImpl
extends
AbstractGenericDAO<ShlkActiveWorkflow, Serializable>
实际类型ShlkActiveWorkflow
将在运行时正确反映。 This is a known workaround to avoid passing a Class<T>
reference to the AbstractGenericDAO
constructor. 这是一种已知的解决方法,可以避免将Class<T>
引用传递给AbstractGenericDAO
构造函数。
If you are worried about the @Autowired
annotation at AbstractGenericDAO
, don't be. 如果您担心AbstractGenericDAO
的@Autowired
注释,请不要这样做。 Spring will correctly wire everything up when you inject a instance of one of its subclasses. 当您注入其中一个子类的实例时,Spring将正确连接所有内容。
Type genericSuperClass = getClass().getGenericSuperclass();
ParameterizedType parametrizedType = null;
while (parametrizedType == null) {
if ((genericSuperClass instanceof ParameterizedType)) {
parametrizedType = (ParameterizedType) genericSuperClass;
} else {
genericSuperClass = ((Class<?>) genericSuperClass).getGenericSuperclass();
}
}
this.itemClass = (Class<T>) parametrizedType.getActualTypeArguments()[0];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.