How to avoid type safety warnings with Hibernate H

2019-01-03 04:27发布

For example I have such query:

Query q = sess.createQuery("from Cat cat");
List cats = q.list();

If I try to make something like this it will show warning "Type safety: The expression of type List needs unchecked conversion to conform to List":

List<Cat> cats = q.list();

Is there a way to avoid it?

16条回答
ら.Afraid
2楼-- · 2019-01-03 05:17

Apparently, the Query.list() method in the Hibernate API is not type safe "by design", and there are no plans to change it.

I believe the simplest solution to avoid compiler warnings is indeed to add @SuppressWarnings("unchecked"). This annotation can be placed at the method level or, if inside a method, right before a variable declaration.

In case you have a method that encapsulates Query.list() and returns List (or Collection), you also get a warning. But this one is suppressed using @SuppressWarnings("rawtypes").

The listAndCast(Query) method proposed by Matt Quail is less flexible than Query.list(). While I can do:

Query q = sess.createQuery("from Cat cat");
ArrayList cats = q.list();

If I try the code below:

Query q = sess.createQuery("from Cat cat");
ArrayList<Cat> cats = MyHibernateUtils.listAndCast(q);

I'll get a compile error: Type mismatch: cannot convert from List to ArrayList

查看更多
甜甜的少女心
3楼-- · 2019-01-03 05:19

A good solution to avoid type safety warnings with hibernate query is to use a tool like TorpedoQuery to help you to build type safe hql.

Cat cat = from(Cat.class);
org.torpedoquery.jpa.Query<Entity> select = select(cat);
List<Cat> cats = select.list(entityManager);
查看更多
Animai°情兽
4楼-- · 2019-01-03 05:20

Using @SuppressWarnings everywhere, as suggested, is a good way to do it, though it does involve a bit of finger typing each time you call q.list().

There are two other techniques I'd suggest:

Write a cast-helper

Simply refactor all your @SuppressWarnings into one place:

List<Cat> cats = MyHibernateUtils.listAndCast(q);

...

public static <T> List<T> listAndCast(Query q) {
    @SuppressWarnings("unchecked")
    List list = q.list();
    return list;
}

Prevent Eclipse from generating warnings for unavoidable problems

In Eclipse, go to Window>Preferences>Java>Compiler>Errors/Warnings and under Generic type, select the checkbox Ignore unavoidable generic type problems due to raw APIs

This will turn off unnecessary warnings for similar problems like the one described above which are unavoidable.

Some comments:

  • I chose to pass in the Query instead of the result of q.list() because that way this "cheating" method can only be used to cheat with Hibernate, and not for cheating any List in general.
  • You could add similar methods for .iterate() etc.
查看更多
Rolldiameter
5楼-- · 2019-01-03 05:25

We use @SuppressWarnings("unchecked") as well, but we most often try to use it only on the declaration of the variable, not on the method as a whole:

public List<Cat> findAll() {
    Query q = sess.createQuery("from Cat cat");
    @SuppressWarnings("unchecked")
    List<Cat> cats = q.list();
    return cats;
}
查看更多
太酷不给撩
6楼-- · 2019-01-03 05:25

No, but you can isolate it into specific query methods and suppress the warnings with a @SuppressWarnings("unchecked") annotation.

查看更多
甜甜的少女心
7楼-- · 2019-01-03 05:25

If you don't want to use @SuppressWarnings("unchecked") you can do the following.

   Query q = sess.createQuery("from Cat cat");
   List<?> results =(List<?>) q.list();
   List<Cat> cats = new ArrayList<Cat>();
   for(Object result:results) {
       Cat cat = (Cat) result;
       cats.add(cat);
    }

FYI - I created a util method that does this for me so it doesn't litter my code and I don't have to use @SupressWarning.

查看更多
登录 后发表回答