2011-08-28 106 views
3

,我有以下的Hibernate代碼:Eclipse的警告:安全型(Java泛型)

List<Book> result;  

result = hibernateTemplate.execute(new HibernateCallback() { 
     public Object doInHibernate(Session session) throws HibernateException, SQLException { 
      Query query = session.createQuery("SELECT DISTINCT b FROM Book as b LEFT JOIN FETCH b.authors"); 

      List list = query.list(); 

      return list; 
     } 
    }); 

我越來越開始hibernateTemplate.execute(...以下警告:

Multiple markers at this line 
    - HibernateCallback is a raw type. References to generic type HibernateCallback<T> should be parameterized 
    - Type safety: The expression of type new HibernateCallback(){} needs unchecked conversion to conform to HibernateCallback<Object> 
    - Type safety: Unchecked invocation execute(new HibernateCallback(){}) of the generic method execute(HibernateCallback<T>) of type 
    HibernateTemplate 
    - Type safety: The expression of type new HibernateCallback(){} needs unchecked conversion to conform to HibernateCallback<List<Book>> 
    - Type safety: The expression of type List needs unchecked conversion to conform to List<Book> 

所以這是非常艱難的。

能否請您解釋一下

  1. 是什麼編譯器看到對什麼期望,爲什麼?

  2. 解決這些警告的最安全方法是什麼......即不是@SuppressWarnings("unchecked")

我試圖出現在下面的鏈接的建議: https://forums.oracle.com/forums/thread.jspa?threadID=1182661 (第二個建議,從三個出現在頁面的底部)......但它沒有工作。

謝謝!

P.S.我知道如何解決由於List list = query.list();而導致的其他警告,這就是爲什麼我沒有在我的問題中提及它。

PS-2根據Eclipse中,該方法的簽名是<Object> Object org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateCallback<Object> action) throws DataAccessException

回答

2

該類的簽名是HibernateCallback<T>,並定義了一個方法T doInHibernate(Session)但你不提供類型參數T - 這就是編譯器抱怨:這不知道你是你的代碼實際上是導致List<Book>那符合你的result變量。

你是正確的,加入@SuppressWarnings是不是一個好主意(它實際上並沒有增加類型安全),試試這個來代替:

List<Book> result = hibernateTemplate.execute(new HibernateCallback<List<Book>>() { 
    public List<Book> doInHibernate(Session session) throws HibernateException, SQLException { 
     Query query = session.createQuery("SELECT DISTINCT b FROM Book as b LEFT JOIN FETCH b.authors"); 

     List list = query.list(); 

     return list; 
    } 
}); 

這臺類型參數T你期望的結果類型的List<Book>,尤其這意味着:

  • new HibernateCallback<List<Book>>(),而不是僅僅new HibernateCallback()
  • 這就要求public Object doInHibernate(Session ...成爲public List<Book> doInHibernate(Session ...

這仍然讓unparameterized List list = query.list();,你可以在其中一個方法處理描述How to avoid type safety warnings with Hibernate HQL results?(我個人比較喜歡鑄造輔助方法提到那裏)。

+0

謝謝!你的回答非常有幫助,並解決了這個問題。在應用第一次更改之後,很容易找出第二個應該是什麼(通過簽名或通過Eclipse的提示)。我的問題是,我應該如何從警告信息等中得出第一個改變? – rapt

+0

每當編譯器警告「X是一種原始類型」時,代碼中的某處就缺少類型參數。最近的框架/庫不會給你一個無類型的集合,所以它通常有助於查看你正在使用的類的源代碼或API文檔。有時候,像Eclipse這樣的IDE也可以使用automagic CTRL + 1「快速修復」快捷鍵來推斷類型參數: –

+0

再次感謝提示! – rapt

0

難道不只是...

new HibernateCallback<List>()... 

這大概意味着該方法返回的類型將是一個列表,而不是對象。儘管如此,你還需要指定List類型呢?