2012-06-16 7 views
12

Ich bin mit diesem Problem für eine lange Zeit fest. Ich suchte dieses Problem für einige Zeit, aber keiner der Lösung funktionierte.java.lang.Class kann nicht in java.lang.reflect.ParameterizedType umgewandelt werden

Struktur:

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 

ich auch <context:component-scan> bin mit meiner application-config.xml + <tx:annotation-driven /> in meinem application-config.xml.

Bitte geben Sie einige Informationen zur Behebung dieses Problems an.

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

Wir brauchen mehr Code aus der Klasse ** ** com.workflow.dao.AbstractGenericDAO –

+0

Haben Sie wirklich brauchen 'AbstractGenericDAO' mit' @ Repository' kommentiert werden? Aus Ihrer Architektur sieht es so aus, als wäre es nur sinnvoll, den spezialisierteren Typ zu injizieren. Denken Sie daran, dass jedes [Repository] (http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Repository.html) definitionsgemäß eine "@ Komponente" ist, die verkabelt werden kann. –

+0

Ich habe gerade einen Code für AbstractGenericDAO.java hinzugefügt – user864077

Antwort

14

entfernen @Repository Anmerkung aus AbstractGenericDAO und es abstract machen:

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

Ihr Problem tritt auf, weil @Repository eine Spezialisierung von @Component ist, was bedeutet, dass Frühling wird versuchen AbstractGenericDAO Instanzen für die Injektion zu erstellen. Da AbstractGenericDAO geordnete Klasse (Object) nicht generisch ist, werden Sie nicht in der Lage sein, seine Type zu ParameterizedType, zu niedergeschlagen und so wird diese Codezeile nicht (in der gleichen Art und Weise, dass es wäre, wenn man versucht, es mit new AbstractGenericDAO() manuell zu instanziiert):

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

Die spezialisierte Klasse ShlkActiveWorkflowDAOImpl noch mit @Repository kommentiert werden soll. Wenn spring versucht, eine Instanz dieser Klasse zu erstellen, wird ein impliziter Aufruf des Konstruktors AbstractGenericDAO ausgeführt, aber dieses Mal wird die oben erwähnte Codezeile wie erwartet ausgeführt. Dies geschieht, weil getClass()ShlkActiveWorkflowDAOImpl.class zurückgibt, was eine Unterklasse des generischen AbstractGenericDAO ist (so dass die Abwärtswandlung zu ParameterizedType funktioniert).

Seit ShlkActiveWorkflowDAOImplextendsAbstractGenericDAO<ShlkActiveWorkflow, Serializable> wird der tatsächliche Typ ShlkActiveWorkflow zur Laufzeit korrekt wiedergegeben. Dies ist eine bekannte Problemumgehung, um zu vermeiden, dass eine Class<T> Referenz auf den AbstractGenericDAO-Konstruktor übergeben wird.

Wenn Sie besorgt sind über die @Autowired Annotation bei AbstractGenericDAO, nicht sein. Spring wird alles richtig verkabeln, wenn Sie eine Instanz einer seiner Unterklassen injizieren.

+0

Danke. Dies funktioniert gut, aber wenn ich eine weitere Annotation in ShlkActiveWorkflowDAOImpl hinzugefügt habe, bekomme ich die gleiche Ausnahme. – user864077

+0

Ich habe die interne Annotation '@Timed' in eine der Methoden von ShlkActiveWorkflowDAOImpl eingefügt – user864077

+0

Ich denke, Sie sollten ein neues Thema für diesen Fehler öffnen. Wie auch immer, Sie sollten '@ Timed' und andere Testanmerkungen nicht in Ihrer Entwicklungsschicht verwenden. Erstellen Sie ein separates [Testen] (http://static.springsource.org/spring/docs/3.0.x/reference/testing.html # Unit-Testing) Ebene und injizieren Sie Ihr Objekt (oder ein Mock). –

-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

Warum negative Punktzahl? Es ist möglich, dass Spring-Klasse abstraktGenericDAO durch cglib, so dass wir Hierarchie überprüfen müssen –

Verwandte Themen