2012-06-16 16 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 

私もapplication-config.xmlの私application-config.xml + <tx:annotation-driven /><context:component-scan>を使用しています。

この問題の解決方法に関する情報を入力してください。

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'でアノテートする必要がありますか?あなたのアーキテクチャからは、より特殊なタイプを注入することが理にかなっているように見えます。すべての[リポジトリ](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Repository.html)は定義上、配線可能な「@コンポーネント」であることを覚えておいてください。 –

+0

AbstractGenericDAO.javaのコードを – user864077

答えて

14

AbstractGenericDAOから@Repository注釈を削除し、それabstractます

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

@Repositoryは、春には、注射用AbstractGenericDAOインスタンスを作成しようとすることを意味し@Componentの専門であるためあなたの問題が発生します。 AbstractGenericDAOスーパークラス(Object)は一般的ではないため、TypeParameterizedTypeにダウンキャストすることはできません。このコード行は、new AbstractGenericDAO()を使用して手動でインスタンス化しようとした場合と同じ方法で失敗します。

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

特殊クラスShlkActiveWorkflowDAOImplには、まだ@Repositoryという注釈が付けられます。 Springがこのクラスのインスタンスを作成しようとすると、AbstractGenericDAOコンストラクタへの暗黙の呼び出しが行われますが、今回は上記のコード行が期待どおりに実行されます。これは、getClass()AbstractGenericDAOのサブクラスであるShlkActiveWorkflowDAOImpl.classを返すためです(したがって、ダウンキャストはParameterizedTypeになります)。

ShlkActiveWorkflowDAOImplextendsAbstractGenericDAO<ShlkActiveWorkflow, Serializable>実際のタイプShlkActiveWorkflowは、実行時に正しく反映されます。これは、AbstractGenericDAOコンストラクタへの参照をClass<T>に渡すことを避けるための既知の回避策です。

注釈がAbstractGenericDAOにあると心配している場合は、そのようにしないでください。 Springは、そのサブクラスの1つのインスタンスを挿入すると、すべてを正しく接続します。

+0

ありがとうございます。これはうまく動作しますが、ShlkActiveWorkflowDAOImpl内に注釈をもう1つ追加した場合、同じ例外が発生します。 – user864077

+0

ShlkActiveWorkflowDAOImplのメソッドの1つに内部アノテーション '@Timed'を追加しました – user864077

+0

このエラーの新しいトピックを開くべきだと思います。とにかく、開発レイヤーで '@ 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をプロキシしている可能性があるため、チェック階層が必要です –

関連する問題