2012-05-26 109 views
0

我目前正在開發集成了Hibernate的Spring MVC項目。純Spring MVC部分(DispatcherServlet +請求映射)工作正常。現在,我必須解決的問題非常奇怪:我讀過「使用Hibernate進行Java持久化」,我試圖以與本書中介紹的方式類似的方式設計持久層。也就是說,我設計了兩個並行層次結構:一個用於實現類,另一個用於接口。Spring MVC + Hibernate DAO:無法連接bean

所以,我有一個名爲GenericDaoImpl的抽象類,它實現了GenericDao接口。然後我有一個名爲AdvertisementDaoImpl的具體類,它擴展了GenericDaoImpl並實現了AdvertisementDao接口(它擴展了GenericDao)。

然後,在一個服務bean(標有@Service的類)中,我將自動裝配我的dao類。

這裏是我的問題:

  • 自動裝配實現接口一個DAO類,但伸出我的抽象GenericDaoImpl類:OK
  • 自動裝配我AdvertisementDaoImpl實現了AdvertisementDao接口和擴展我的抽象GenericDaoImpl類:導致bean初始化異常。

我在DAO層次結構頂部的抽象類將處理常見CRUD方法的所有樣板代碼。所以,我一定要保留它。

有沒有人有解釋?

這裏是代碼的摘錄:

public abstract class GenericDaoImpl <T, ID extends Serializable> implements BeanPostProcessor, GenericDao<T, ID>{ 
    @Autowired(required=true) 
    private SessionFactory sessionFactory; 
    private Session currentSession; 
    private Class<T> persistentClass; 

... 
} 


@Repository 
public class AdvertisementDaoImpl extends GenericDaoImpl<Advertisement, Long> implements AdvertisementDao { 

... 


    public List<Advertisement> listAdvertisementByType(AdvertisementType advertisementType, Class<? extends Good> type) { 
     return null; 
    } 

} 

@Service 
public class AdvertisementServiceImpl implements AdvertisementService{ 
    @Autowired(required=false) 
    private AdvertisementDao advertisementDao; 

    public List<Advertisement> listAllAdvertisements() { 

     return null; 
    } 

} 

這裏的堆棧跟蹤最相關的部分(至少,我想這是):

嵌套的例外是 org.springframework.beans .factory.BeanCreationException:不能 autowire字段:be.glimmo.service.AdvertisementService be.glimmo.controller.HomeController.advertisementService;嵌套0​​例外是java.lang.IllegalArgumentException異常:無法設置 be.glimmo.service.AdvertisementService場 be.glimmo.controller.HomeController.advertisementService到 be.glimmo.dao.AdvertisementDaoImpl

這是我的Spring configuration(鏈接pastebin.com):

+0

你必須告訴我們什麼是你所得到的例外。 –

+2

有點偏移,但爲什麼generic dao實現BeanPostProcessor? –

+0

我有我的通用dao實現BeanPostProcessor,以便其持有類型化類的屬性將在bean實例化時初始化。但它主要是爲了測試目的,因爲它絕對沒有必要 – kyiu

回答

0

我相信你應該在你的事務管理配置中使用proxy-target-class

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

種你描述匹配Spring Transaction Management提到的那些問題的症狀(查找表10.2)和AOP proxying with Spring

如果目標對象被代理至少一個接口 然後是JDK動態代理將使用工具。所有由目標類型實現的接口 將被代理。如果目標對象 未實現任何接口,則將創建CGLIB代理。

所以,當CGLIB是不存在默認情況下,你把所有的方法,從實現的接口來,但你會錯過的層次結構中來自超類中的方法代理,這就是爲什麼你會得到這個異常。

0

經過幾次更多的測試後發現問題是由我的抽象GenericDaoImpl類實現BeanPostProcessor接口引起的:出於某種原因,來自此接口的方法不僅在此bean實例化處執行,而且還在處執行每個bean處理。因爲在我的BeanPostProcessor鉤子方法中,我檢索泛型參數化類型,當這些方法對不在我的DAO層次結構中的類執行時,它們最終會產生運行時異常(更具體地說,是ClassCastException)。

所以,要解決這個問題,我有我的GenericDaoImpl類沒有實現BeanPostProcessor接口了,我感動的鉤子方法的身體在空構造器。