2012-06-16 100 views
12

我被這個問題困住了很長時間。我搜索了一段時間的這個問題,但沒有解決方案的工作。java.lang.Class不能轉換爲java.lang.reflect.ParameterizedType

結構:

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 

中我也用我的<context:component-scan>application-config.xmlapplication-config.xml + <tx:annotation-driven />

請提供一些有關如何解決此問題的信息。

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 
+0

我們需要更多的代碼從類** ** com.workflow.dao.AbstractGenericDAO –

+0

你真的需要'AbstractGenericDAO'與'@ Repository'被標註?從你的架構看來,注入更專業化的類型纔有意義。請記住,每個[Repository](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Repository.html)定義爲可以連線的@ Component。 –

+0

我只是爲AbstractGenericDAO.java – user864077

回答

14

AbstractGenericDAO刪除@Repository註釋,並使其abstract:發生

public abstract class AbstractGenericDAO<T extends Serializable, ID extends Serializable> 
    implements GenericDAO<T, ID> 

你的問題,因爲@Repository@Component一個特例,這意味着春天將嘗試創造注射AbstractGenericDAO實例。由於AbstractGenericDAO超類(Object)不是通用的,因此您將無法將其Type向下轉換爲ParameterizedType,因此該行代碼將失敗(與以下情況的方式相同):

this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 

專業類ShlkActiveWorkflowDAOImpl仍然應註明@Repository。當spring試圖創建這個類的實例時,會發生對AbstractGenericDAO構造函數的隱式調用,但是這次上面提到的代碼行將按預期運行。發生這種情況的原因是getClass()返回ShlkActiveWorkflowDAOImpl.class,它是通用AbstractGenericDAO的子類(所以downcast到ParameterizedType工作)。

由於ShlkActiveWorkflowDAOImplextendsAbstractGenericDAO<ShlkActiveWorkflow, Serializable>實際類型ShlkActiveWorkflow將在運行時正確反映。這是一個已知的解決方法,以避免將Class<T>引用傳遞給AbstractGenericDAO構造函數。

如果您擔心註釋AbstractGenericDAO,不要這樣做。當你注入一個子類的實例時,Spring將正確地連接所有東西。

+0

謝謝。這工作正常,但是當我在ShlkActiveWorkflowDAOImpl中添加了一個註釋時,我得到了相同的異常。 – user864077

+0

我已經在ShlkActiveWorkflowDAOImpl – user864077

+0

的其中一種方法中添加了內部註釋'@Timed'我想你應該爲這個錯誤開一個新的主題。無論如何,你不應該在開發層使用'@ Timed'和其他測試註釋。創建一個單獨的[測試](http://static.springsource.org/spring/docs/3.0.x/reference/testing。html#unit-testing)層並注入你的對象(或模擬)。 –

-2
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]; 
+0

爲什麼負分? 有可能是cglib的spring代理類AbstractGenericDAO,所以我們需要檢查層次結構 –

相關問題