2016-02-21 62 views
0

在傳統項目中,我添加一個新的方法的DAO,然後我寫了一個單元測試來測試新方法當加@Transactional無法初始化DAO豆

FooDAO dao = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}).getBean("FooDAO"); 
@Test 
public void test_getUnenabledArtisanIdsByReverseTime(){ 
    String reverseTimeStr = "2016-02-18 19:00"; 
    List<String> artisanIds = new ArrayList<>(); 
    artisanIds.add("1"); 
    artisanIds.add("2"); 
    dao.getUnenabledArtisanIdsByReverseTime(artisanIds, reverseTimeStr); 
} 

失敗,拋出異常

下方
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here 

然後,添加以下配置在applicationContext.xml

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> 

並添加@Transactional以上的新方法再次

@Transactional 
public List<String> getUnenabledArtisanIdsByReverseTime(List<String> artisanIds, String reverseTimeStr) 

然後執行單元測試,失敗過,但它的另一個異常

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'FooDAO' defined in file [/home/zhuguowei/workspace/myapp/WebContent/WEB-INF/classes/com/foo/artisan/repository/FooDAO.class]: 
Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: 
Could not generate CGLIB subclass of class [class com.foo.artisan.repository.FooDAO]: 
Common causes of this problem include using a final class or a non-visible class; nested exception is net.sf.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:527) 

很奇怪的道是公開的,而不是最後一類

@Component 
public class FooDAO extends BaseDaoHiber4Impl<Foo> 

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

那麼這個問題的原因是什麼?如何解決這個問題?

回答

1

cglib代理的工作原理是創建一個新類,擴展目標類並覆蓋每個方法。

在創建代理,你的構造失敗:

(ParameterizedType) getClass().getGenericSuperclass() 

的getClass()現在的代理,並getGenericSuperclass()是當前類(FooDAO),這是不是一個ParameterizedType

可能的解決方法:

  1. 它看起來像你正試圖重新實現彈簧數據:試一試,而不是:-)
  2. 不要使用cglib代理:爲你的DAO定義一個接口,讓FooDAO實現它,並注入這個接口而不是你的類。
  3. 處理情況FooDAO被延長的情況下:通過所有getGenericSuperclass迭代()查找第ParameterizedType實例
+0

謝謝!但可以有更好的方式解決這個問題 – zhuguowei

+0

謝謝!但你知道這是一個遺留項目 – zhuguowei

+0

你確實存在某種方式可以讓dao方法不必在交易中,例如, ' false' – zhuguowei