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.
We had same problem. But it wasn't a big deal for us because we had to solve other more major issues with Hibernate Query and Session.
Specifically:
control when a transaction could be committed. (we wanted to count how many times a tx was "started" and only commit when the tx was "ended" the same number of times it was started. Useful for code that doesn't know if it needs to start a transaction. Now any code that needs a tx just "starts" one and ends it when done.)
Performance metrics gathering.
Delaying starting the transaction until it is known that something will actually be done.
More gentle behavior for query.uniqueResult()
So for us, we have:
Create an interface (AmplafiQuery) that extends Query
Create a class (AmplafiQueryImpl) that extends AmplafiQuery and wraps a org.hibernate.Query
Create a Txmanager that returns a Tx.
Tx has the various createQuery methods and returns AmplafiQueryImpl
And lastly,
AmplafiQuery has a "asList()" that is a generic enabled version of Query.list()
AmplafiQuery has a "unique()" that is a generic enabled version of Query.uniqueResult() ( and just logs an issue rather than throwing an exception)
This is a lot of work for just avoiding @SuppressWarnings. However, like I said (and listed) there are lots of other better! reasons to do the wrapping work.
It's not an oversight or a mistake. The warning reflects a real underlying problem - there is no way that the java compiler can really be sure that the hibernate class is going to do it's job properly and that the list it returns will only contain Cats. Any of the suggestions here is fine.
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:
It is been a long time since the question was asked but I hope my answer might be helpful to someone like me.
If you take a look at javax.persistence api docs, you will see that some new methods have been added there since Java Persistence 2.0. One of them is createQuery(String, Class<T>) which returns TypedQuery<T>. You can use TypedQuery just as you did it with Query with that small difference that all operations are type safe now.
Newer versions of Hibernate now support a type safe Query<T> object so you no longer have to use @SuppressWarnings or implement some hack to make the compiler warnings go away. In the Session API, Session.createQuery will now return a type safe Query<T> object. You can use it this way: