How to Avoid Type Safety Warnings with Hibernate Hql Results

How to avoid type safety warnings with Hibernate HQL results?

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.

Avoiding Type Safety Warnings Using Hibernate Query.list()

The most important thing to remember is that warnings are due to your compiler, not hibernate - you can tell your compiler to ignore unimplemented generics. By using HQL, we are querying for data in a type safe way that, unfortunately, java does not have the ability to verify.

There are a lot of ways to get around the syntactical ugliness of hibernate casting , like :

1) use @suppressWarnings where casting or

2) use the Collections.checkedList method to create the new list.

See also : How to avoid type safety warnings with Hibernate HQL results?

Avoid safety warnings with Hibernate HQL results?

Use Collections.checkedList()

List<MenuItems> cats = Collections.checkedList(cr.list(), MenuItems.class);

Or use @suppressWarnings, which you have specified in your code

Avoid type safety warnings with Hibernate criteria query

Well, you can use:

@SuppressWarnings("unchecked")

before the declaration...

Note that this will only suppress the warning - it won't do anything to make the code safer. In this case, I'd personally be happy enough about this; I'd trust Hibernate to do the right thing.

Hibernate Query Result List and Type safety?

At some place a conversion from the untyped list to the typed list has to happen. This conversion is unsafe. Collections.checkedList would allow you to move the annotation but not more; not very helpful here. The annotation does not "solve" the problem in a technical sense, it just tells the compiler that you know what you do. As the Query interface does not return typed results (for good reason) there is no way around either a warning or the SuppressWarnings annotation.

You should set the annotation and write a meaningful comment why it is justified (i.e. because the type is determined by the HQL query but the interface returns an untyped list).

Eclipse warning: Type safety (Java Generics)

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).

Hibernate Search: Get parametrised result from query without unchecked warnings

No, it's not currently possible to instantiate a type-safe FullTextQuery (reasons below). The recommended approach is this one, which will work fine with Search 5.10 as well as older (pre-5.7) versions:

QueryBuilder queryBuilder = fullTextSession
.getSearchFactory()
.buildQueryBuilder()
.forEntity(Entity.class)
.get();
org.apache.lucene.search.Query luceneQuery = queryBuilder
.keyword()
.onField("field")
.matching("value")
.createQuery();

FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, Entity.class);
List<Entity> result = (List<Entity>) query.list();

Why?

The ability to create a type-safe query is fairly new by ORM standards: it came with JPA 2.1 (ORM 5.2). Before that, the list() method used to return a raw List (without generic type parameters) in ORM, and so did it in Hibernate Search queries.

Hibernate Search did not change to follow ORM, though: FullTextQuery extends org.hibernate.query.Query as a raw type, without any parameter. The reason is, there are mutators on the FullTextQuery object that allow to change the returned objects, and thus the returned type (in particular, the setProjection method). So, even though we could return a FullTextQuery<Entity> when you build a query, that would be misleading, because in some cases you could end up with a FullTextQuery<Entity> that actually returns results of type List<Object[]>.

We explored a few options to resolve this situation, but couldn't find a solution that would both guarantee type-safety and allow to preserve backward compatibility. So we've given up on this for Hibernate Search 5.

In case you're wondering, ORM does not have the same problem, because you specify the exact type you want your query to return when you create your query, and cannot change it afterwards.

In the next major of Hibernate Search, the version 6, this will be solved, however. The new query building APIs require to specify whether the query will return managed entities or an index projections before you create the query. Hibernate Search 6 is not stable yet and is not ready for production, but if you're curious you can find an example here (the asEntity call tells Search what the return type should be).

How to get result element from hibernate with no warning

Try out:

TypedQuery<Product> q = em.createQuery("FROM Product WHERE productCode=:productCode", Product.class);
q.setParameter("productCode", productCode);
if(q.getResultList().isEmpty()) {
return null;
}
List<Product> results = q.getResultList();
Iterator<Product> i = results.iterator();
Product pp = null;
if(i.hasNext()) {
pp = i.next();
}

Edit: I used this source http://www.objectdb.com/java/jpa/query/execute
Very Important:

Both Query and TypedQuery define a getResultList method, but the
version of Query returns a result list of a raw type (non generic)
instead of a parameterized (generic) type



Related Topics



Leave a reply



Submit