2015-02-09 1 views
0

Я использую Spring 3.2.11.RELEASE. У меня есть класс, как в следующем ...Добавление причин @Transactional "java.lang.ClassCastException -> java.lang.Class нельзя отнести к java.lang.reflect.ParameterizedType" exception

@Repository("AssessmentImageDao") 
@Transactional 
public class MyObjectDao extends GenericDAO<MyObject> 
{ 

, в котором супер класс имеет

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

Однако, это приводит к тому, ниже исключение ...

[ERROR]: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframewor[email protected]62b9a65b] to prepare test instance [[email protected]] 
java.lang.IllegalStateException: Failed to load ApplicationContext 
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99) 
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122) 
    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:211) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124) 
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200) 
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153) 
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyObjectDao' defined in file [/Users/davea/Dropbox/workspace/core/target/classes/org/mainco/subco/myproject/dao/MyObjectDao.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.mainco.subco.myproject.dao.MyObjectDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.ClassCastException-->java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:934) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) 
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120) 
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60) 
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:102) 
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:246) 
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64) 
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91) 
    ... 25 more 

Есть ли способ переписать конструктор, чтобы избежать такого исключения или выполнить некоторую другую глобальную конфигурацию, которая бы устранила проблему? Я пытаюсь перечислить каждый из подклассов класса GenericDao.

+0

Вы использовали 'org.springframework.transaction.annotation.Transactional' вместо' javax.transaction.Transactional'? – gerrytan

+0

Хорошее различие, да, я использую org.springframework.transaction.annotation.Transactional. –

ответ

2

Проблема заключается в том, что аннотация @Transactional реализована путем добавления другого уровня в иерархию классов - прокси-класса, который расширяет MyObjectDao для реализации транзакционного поведения. Для объектов этого прокси-класса this.getClass() является прокси-классом, getGenericSuperclass() - это MyObjectDao, а не параметризованный тип GenericDAO<MyObject>.

Вы можете изменить логику немного, так что вы держите глядя вверх getGenericSuperclass цепь до тех пор, пока не найдете ParameterizedType - если родитель является Class вы пытаетесь прародителей, и так далее.

В качестве альтернативы, посмотрите, можете ли вы отложить поиск суперкласса до тех пор, пока он вам не понадобится (когда используется один из методов GenericDAO), а не в конструкторе. Хотя сгенерированный класс прокси расширяет MyObjectDao, он никогда не называет ни один из своих методов суперкласса на this. Прокси перехватывает все вызовы методов, делает логику транзакций, а затем делегирует бизнес-логику отдельному целевому объекту, который является экземпляром MyObjectDao напрямую, а не подклассом.

0

Вы также можете использовать полиморфизм и создать метод public abstract Class<? extends MyObject> getHandledType() в GenericDAO и сделать каждую реализацию представительной.

Или используйте данные весны.

+0

Можете ли вы привести пример кодирования того, как это будет работать? –

+0

@DaveA потребовалось бы «перекодировать каждый из подклассов класса GenericDao», чтобы добавить новый метод ... –

Смежные вопросы