たとえば、私はそのようなクエリがあります:
Query q = sess.createQuery("from Cat cat");
List cats = q.list();
このようなものを作成しようとすると、次の警告が表示されます
Type safety: The expression of type List needs unchecked conversion to conform to List<Cat>
List<Cat> cats = q.list();
それを回避する方法はありますか?
提案されているように、_@SuppressWarnings
_をあらゆる場所で使用するのは良い方法ですが、q.list()
を呼び出すたびに少し指を入力する必要があります。
私が提案する他の2つのテクニックがあります:
キャストヘルパーを書く
すべての_@SuppressWarnings
_を1つの場所にリファクタリングするだけです。
_List<Cat> cats = MyHibernateUtils.listAndCast(q);
...
public static <T> List<T> listAndCast(Query q) {
@SuppressWarnings("unchecked")
List list = q.list();
return list;
}
_
Eclipseが避けられない問題の警告を生成しないようにする
Eclipseで、Window> Preferences> Java> Compiler> Errors/Warningsに移動し、Generic typeでチェックボックス_Ignore unavoidable generic type problems due to raw APIs
_を選択します
これにより、上記のような避けられない類似の問題に対する不要な警告がオフになります。
コメント:
q.list()
の結果の代わりにQuery
を渡すことを選択しました。これは、この「チート」メソッドはHibernateでチートするためにのみ使用でき、List
一般に。.iterate()
などにも同様のメソッドを追加できます。質問が出されてから長い時間が経ちましたが、私の答えが私のような人に役立つことを願っています。
Javax.persistence api docs を見ると、_Java Persistence 2.0
_以降にいくつかの新しいメソッドが追加されていることがわかります。それらの1つはcreateQuery(String, Class<T>)
で、_TypedQuery<T>
_を返します。 TypedQuery
を使用したときと同じようにQuery
を使用できます。ただし、すべての操作がタイプセーフになるというわずかな違いがあります。
したがって、次のようにコードをsmthに変更するだけです。
_Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
_
そして、あなたはすべて設定されています。
@SuppressWarnings("unchecked")
も使用しますが、ほとんどの場合、メソッド全体ではなく、変数の宣言でのみ使用しようとします。
public List<Cat> findAll() {
Query q = sess.createQuery("from Cat cat");
@SuppressWarnings("unchecked")
List<Cat> cats = q.list();
return cats;
}
TypedQuery
の代わりにQuery
を使用してみてください。たとえば、これの代わりに:-
Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
これを使って:-
TypedQuery<Cat> q1 = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q1.list();
このコードでは、呼び出しメソッドに次の注釈を付けます。
@SuppressWarnings( "unchecked")
ハックのように見えますが、共同開発者が最近チェックし、それが私たちにできるすべてであることがわかりました。
どうやら、Hibernate APIのQuery.list()メソッドは「設計上」タイプセーフではなく、 変更する予定はありません があります。
コンパイラの警告を回避する最も簡単な解決策は、実際に@SuppressWarnings( "unchecked")を追加することだと思います。この アノテーションを配置できます メソッドレベル、またはメソッド内の場合は変数宣言の直前。
Query.list()をカプセル化してList(またはCollection)を返すメソッドがある場合、警告も表示されます。しかし、これは@SuppressWarnings( "rawtypes")を使用して抑制されます。
Matt Quailによって提案されたlistAndCast(Query)メソッドは、Query.list()よりも柔軟性が低くなります。私ができる間:
Query q = sess.createQuery("from Cat cat");
ArrayList cats = q.list();
以下のコードを試してみると:
Query q = sess.createQuery("from Cat cat");
ArrayList<Cat> cats = MyHibernateUtils.listAndCast(q);
コンパイルエラーが発生します:タイプの不一致:ListからArrayListに変換できません
それは見落としや間違いではありません。警告は実際の根本的な問題を反映しています-Javaコンパイラがhibernateクラスが適切に仕事をすることを確実にし、返されるリストにCatsのみが含まれることを確実にする方法はありません。ここでの提案はすべて問題ありません。
いいえ。ただし、特定のクエリメソッドに分離し、@SuppressWarnings("unchecked")
アノテーションを使用して警告を抑制することができます。
Hibernateの新しいバージョンでは、タイプセーフQuery<T>
オブジェクトを使用するため、@SuppressWarnings
またはハッカーを実装して、コンパイラの警告を消します。 セッションAPI 、Session.createQuery
はタイプセーフを返しますQuery<T>
オブジェクト。次のように使用できます。
Query<Cat> query = session.createQuery("FROM Cat", Cat.class);
List<Cat> cats = query.list();
クエリ結果がCatを返さない場合にも使用できます。
public Integer count() {
Query<Integer> query = sessionFactory.getCurrentSession().createQuery("SELECT COUNT(id) FROM Cat", Integer.class);
return query.getSingleResult();
}
または、部分選択を行う場合:
public List<Object[]> String getName() {
Query<Object[]> query = sessionFactory.getCurrentSession().createQuery("SELECT id, name FROM Cat", Object[].class);
return query.list();
}
同じ問題がありました。しかし、Hibernate QueryとSessionに関する他のより大きな問題を解決しなければならなかったため、それは大したことではありませんでした。
具体的には:
したがって、私たちには次のものがあります。
そして最後に、
AmplafiQueryには、Query.list()の汎用有効バージョンである「asList()」があります。AmplafiQueryには、Query.uniqueResult()の汎用有効バージョンである「unique()」があります。例外)
これは、@ SuppressWarningsを回避するための多くの作業です。しかし、私が言ったように(そしてリストされているように)より良いものがたくさんあります!ラッピング作業を行う理由。
Joe Deanのソリューションは興味深いように見えますが、それだけの価値があると思います。警告を取り除くために、新しいリストを作成し、すべての要素をループしますか?
(申し訳ありませんが、何らかの理由で彼のソリューションに直接コメントを追加することはできません)
これは古いことは知っていますが、今日のMatt Quails Answerで注意すべき2点があります。
この
List<Cat> cats = Collections.checkedList(Cat.class, q.list());
これであるべき
List<Cat> cats = Collections.checkedList(q.list(), Cat.class);
これから
List list = q.list();
これに
List<T> list = q.list();
元の返信タグマーカーがブラウザによって削除された場合、他の警告が明らかに減少します。