简体   繁体   中英

Eclipse warning: Type safety (Java Generics)

I have the following Hibernate code:

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;
        }
    });

I am getting the following warnings starting at 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>

So this is really tough.

Could you please explain

  1. What does the compiler see versus what it expects, and why?

  2. What is the safest way to fix these warnings... ie not by @SuppressWarnings("unchecked") ?

I have tried the proposal appearing in the following link: https://forums.oracle.com/forums/thread.jspa?threadID=1182661 (the second suggestion out of the three appearing at the bottom of the page).... however it did not work.

Thanks!

PS I do know how to solve the other warning I am supposed to get due to the List list = query.list(); , this is why I am not mentioning it in my question.

PS-2 According to Eclipse, the signature of the method is <Object> Object org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateCallback<Object> action) throws DataAccessException

The signature of that class is HibernateCallback<T> and defines a method T doInHibernate(Session) but you don't supply the type parameter T -- that's what the compiler is complaining about: It's not sure you're your code is actually resulting in a List<Book> that fits into your result variable.

You are correct in that adding @SuppressWarnings isn't a good idea (it doesn't increase actually type safety), try this instead:

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;
    }
});

This sets the type parameter T to your expected result type of List<Book> , in particular this means:

  • new HibernateCallback<List<Book>>() instead of just new HibernateCallback()
  • this then demands public Object doInHibernate(Session ... to become public List<Book> doInHibernate(Session ...

This still leaves the unparameterized List list = query.list(); which you could handle in one of the ways describe in How to avoid type safety warnings with Hibernate HQL results? (I'd personally prefer the cast-helper approach mentioned there).

Is it not just ...

new HibernateCallback<List>()...

Which presumably means the method return type would be a List rather than Object. Though then you'd need to specify the List type too?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM