2011-08-28 102 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类型呢?