Par exemple, j’ai une telle requête:
Query q = sess.createQuery("from Cat cat"); List cats = q.list();
Si j’essaie de faire quelque chose comme ça, il affichera un avertissement “Type safety: L’expression de type List nécessite une conversion non vérifiée pour se conformer à List”:
List cats = q.list();
Est-il possible de l’éviter?
L’utilisation de @SuppressWarnings
partout, comme suggéré, est un bon moyen de le faire, même si cela nécessite un peu de saisie à chaque fois que vous appelez q.list()
.
Il y a trois autres techniques que je suggérerais:
Collections.checkedList()
Remplacez votre affectation par ceci:
List cats = Collections.checkedList(q.list(), Cat.class);
Vous pourriez vouloir vérifier le javadoc pour cette méthode , en particulier en ce qui concerne les equals
et hashCode
.
Ecrivez un assistant
Il suffit de refactoriser tous vos @SuppressWarnings
en un seul endroit:
List cats = MyHibernateUtils.listAndCast(q); ... public static List listAndCast(Query q) { @SuppressWarnings("unchecked") List list = q.list(); return list; }
Empêcher Eclipse de générer des avertissements pour les problèmes inévitables
Dans Eclipse, accédez à Fenêtre> Préférences> Java> Compilateur> Erreurs / Avertissements et sous Type générique, cochez la case Ignore unavoidable generic type problems due to raw APIs
Cela désactivera les avertissements inutiles pour des problèmes similaires, comme celui décrit ci-dessus, qui sont inévitables.
Certains commentaires:
Query
au lieu du résultat de q.list()
car cette méthode de «sortingche» ne peut être utilisée que pour tromper avec Hibernate et non pour tromper une List
en général. .iterate()
etc. Nous utilisons aussi @SuppressWarnings("unchecked")
, mais nous essayons le plus souvent de ne l’utiliser que sur la déclaration de la variable, pas sur la méthode dans son ensemble:
public List findAll() { Query q = sess.createQuery("from Cat cat"); @SuppressWarnings("unchecked") List cats = q.list(); return cats; }
Il y a longtemps que la question a été posée, mais j’espère que ma réponse pourrait être utile à quelqu’un comme moi.
Si vous jetez un coup d’œil aux documents d’ api javax.persistence, vous verrez que de nouvelles méthodes ont été ajoutées depuis Java Persistence 2.0
. L’un d’eux est createQuery(Ssortingng, Class
qui renvoie TypedQuery
. Vous pouvez utiliser TypedQuery
comme vous l’avez fait avec Query
avec cette petite différence que toutes les opérations sont maintenant de type sécurisé.
Alors, changez simplement votre code en smth comme ceci:
Query q = sess.createQuery("from Cat cat", Cat.class); List cats = q.list();
Et vous êtes tous ensemble.
Essayez d’utiliser TypedQuery
au lieu de Query
. Par exemple au lieu de cela: –
Query q = sess.createQuery("from Cat cat", Cat.class); List cats = q.list();
Utilisez ceci:-
TypedQuery q1 = sess.createQuery("from Cat cat", Cat.class); List cats = q1.list();
Dans notre code, nous annotons les méthodes d’appel avec:
@SuppressWarnings (“non vérifié”)
Je sais que cela semble être un hack, mais un co-développeur a vérifié récemment et a trouvé que c’était tout ce que nous pouvions faire.
Apparemment, la méthode Query.list () de l’API Hibernate n’est pas de type “par conception”, et il n’est pas prévu de la modifier .
Je pense que la solution la plus simple pour éviter les avertissements du compilateur est d’append @SuppressWarnings (“non vérifié”). Cette annotation peut être placée au niveau de la méthode ou, si dans une méthode, juste avant une déclaration de variable.
Si vous avez une méthode qui encapsule Query.list () et renvoie List (ou Collection), vous obtenez également un avertissement. Mais celui-ci est supprimé en utilisant @SuppressWarnings (“rawtypes”).
La méthode listAndCast (Query) proposée par Matt Quail est moins flexible que Query.list (). Bien que je puisse faire:
Query q = sess.createQuery("from Cat cat"); ArrayList cats = q.list();
Si j’essaye le code ci-dessous:
Query q = sess.createQuery("from Cat cat"); ArrayList cats = MyHibernateUtils.listAndCast(q);
Je vais obtenir une erreur de compilation: Incompatibilité de type: impossible de convertir de la liste en ArrayList
Ce n’est pas un oubli ou une erreur. L’avertissement reflète un véritable problème sous-jacent – le compilateur Java ne peut en aucun cas être vraiment sûr que la classe hibernate va faire son travail correctement et que la liste renvoyée contiendra uniquement des chats. Toutes les suggestions ici sont bien.
Non, mais vous pouvez l’isoler dans des méthodes de requête spécifiques et supprimer les avertissements avec une @SuppressWarnings("unchecked")
.
Nous avons eu le même problème. Mais ce n’était pas un gros problème pour nous car nous devions résoudre d’autres problèmes plus importants avec Hibernate Query and Session.
Plus précisément:
Donc pour nous, nous avons:
Et enfin,
AmplafiQuery a un “asList ()” qui est une version générique de Query.list () AmplafiQuery a un “unique ()” qui est une version générique de Query.uniqueResult () (et enregistre simplement un problème plutôt que de lancer un exception)
C’est beaucoup de travail pour éviter @SuppressWarnings. Cependant, comme je l’ai dit (et répertorié), il y en a beaucoup d’autres mieux! raisons de faire le travail d’emballage.
Les nouvelles versions de Hibernate prennent désormais en charge un object de type Query
sûr de sorte que vous ne devez plus utiliser @SuppressWarnings
ou implémenter un hack pour que les avertissements du compilateur disparaissent. Dans l’ API de session , Session.createQuery
désormais un object de type sécurisée Query
. Vous pouvez l’utiliser de cette façon:
Query query = session.createQuery("FROM Cat", Cat.class); List cats = query.list();
Vous pouvez également l’utiliser lorsque le résultat de la requête ne renvoie pas un chat:
public Integer count() { Query query = sessionFactory.getCurrentSession().createQuery("SELECT COUNT(id) FROM Cat", Integer.class); return query.getSingleResult(); }
Ou lorsque vous effectuez une sélection partielle:
public List
La solution de Joe Dean semble intéressante, mais pensez-vous que cela en vaut la peine – créez une nouvelle liste et parcourez tous les éléments pour vous débarrasser des avertissements?
(désolé, ne peut pas append un commentaire directement à sa solution pour une raison quelconque)
Je sais que c’est plus vieux mais 2 points à noter dès aujourd’hui dans la réponse de Matt Quails.
Ce
List cats = Collections.checkedList(Cat.class, q.list());
Devrait être ça
List cats = Collections.checkedList(q.list(), Cat.class);
De ceci
List list = q.list();
pour ça
List list = q.list();
réduirait évidemment d’autres avertissements dans les repères de repères d’origine ont été supprimés par le navigateur.
Essaye ça:
Query q = sess.createQuery("from Cat cat"); List> results = q.list(); for (Object obj : results) { Cat cat = (Cat) obj; }
Une bonne solution pour éviter les avertissements de sécurité de type avec une requête d’hibernation consiste à utiliser un outil tel que TorpedoQuery pour vous aider à créer un hql de type sécurisé.
Cat cat = from(Cat.class); org.torpedoquery.jpa.Query select = select(cat); List cats = select.list(entityManager);
Si vous ne souhaitez pas utiliser @SuppressWarnings (“non vérifié”), vous pouvez effectuer les opérations suivantes.
Query q = sess.createQuery("from Cat cat"); List> results =(List>) q.list(); List cats = new ArrayList (); for(Object result:results) { Cat cat = (Cat) result; cats.add(cat); }
FYI – J’ai créé une méthode util qui fait cela pour moi, donc je ne jette pas de code sur mon code et je n’ai pas besoin d’utiliser @SupressWarning.