108

たとえば、次のようなクエリがあります。

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();

それを回避する方法はありますか?

4

15 に答える 15

101

提案されているように、どこでも使用@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で、[ウィンドウ]>[設定]>[Java]>[コンパイラ]>[エラー/警告]に移動し、[ジェネリックタイプ]でチェックボックスを選択します Ignore unavoidable generic type problems due to raw APIs

これにより、上記のような避けられない同様の問題に対する不要な警告がオフになります。

いくつかのコメント:

  • この「不正行為」の方法は、Hibernateでの不正行為にのみ使用でき、一般的な不正行為には使用できないためQuery、結果の代わりに渡すことにしました。q.list()List
  • .iterate()などに同様のメソッドを追加できます。
于 2008-09-23T03:38:11.490 に答える
43

質問されてから長い時間が経ちましたが、私の答えが私のような人に役立つことを願っています.

javax.persistence api docsを見ると、それ以降にいくつかの新しいメソッドが追加されていることがわかりますJava Persistence 2.0。それらの 1 つは、createQuery(String, Class<T>)を返すものTypedQuery<T>です。すべての操作がタイプセーフになったという小さな違いはありTypedQueryますが、使用したのと同じように使用できます。Query

したがって、コードを次のように変更するだけです。

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

これで準備は完了です。

于 2015-05-15T20:24:00.280 に答える
21

同様に使用@SuppressWarnings("unchecked")しますが、ほとんどの場合、メソッド全体ではなく、変数の宣言でのみ使用しようとします。

public List<Cat> findAll() {
    Query q = sess.createQuery("from Cat cat");
    @SuppressWarnings("unchecked")
    List<Cat> cats = q.list();
    return cats;
}
于 2008-09-22T16:55:18.523 に答える
5

どうやら、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);

コンパイル エラーが発生します: Type mismatch: cannot convert from List to ArrayList

于 2012-12-05T17:46:44.297 に答える
5

コードでは、呼び出しメソッドに次の注釈を付けます。

@SuppressWarnings("未チェック")

ハックのように思えますが、共同開発者が最近チェックしたところ、それしかできないことがわかりました.

于 2008-09-22T15:57:42.733 に答える
4

見落としや間違いではありません。警告は実際の根本的な問題を反映しています。Java コンパイラが、休止状態クラスが適切に機能し、返されるリストに Cat のみが含まれていることを実際に確認できる方法はありません。ここでの提案はどれも問題ありません。

于 2009-02-13T02:55:37.613 に答える
2

いいえ、ただし、特定のクエリ メソッドに分離し、@SuppressWarnings("unchecked")注釈を使用して警告を抑制することができます。

于 2008-09-22T15:58:50.297 に答える
1

同じ問題がありました。しかし、Hibernate Query と Session に関する他のより大きな問題を解決しなければならなかったので、それは私たちにとって大したことではありませんでした。

具体的には:

  1. トランザクションをいつコミットできるかを制御します。(tx が「開始」された回数をカウントし、tx が開始されたのと同じ回数「終了」したときにのみコミットしたかったのです。トランザクションを開始する必要があるかどうかがわからないコードに役立ちます。 tx を必要とするすべてのコードは、tx を「開始」し、完了したら終了します。)
  2. パフォーマンス メトリックの収集。
  3. 何かが実際に行われることがわかるまで、トランザクションの開始を遅らせる。
  4. query.uniqueResult() のより穏やかな動作

したがって、私たちには次のものがあります。

  1. Queryを拡張するインターフェース(AmplafiQuery)を作成する
  2. AmplafiQuery を拡張し、org.hibernate.Query をラップするクラス (AmplafiQueryImpl) を作成します。
  3. Tx を返す Txmanager を作成します。
  4. Tx にはさまざまな createQuery メソッドがあり、AmplafiQueryImpl を返します

そして最後に、

AmplafiQuery には、Query.list() の一般的な有効バージョンである「asList()」があります。AmplafiQuery には、Query.uniqueResult() の一般的な有効バージョンである「unique()」があります。例外)

これは、@SuppressWarnings を回避するだけでも大変な作業です。しかし、私が言った(そしてリストした)ように、他にももっと良いものがたくさんあります!ラッピング作業を行う理由。

于 2009-02-13T02:08:02.673 に答える
0

これは古いことは知っていますが、今日の時点で Matt Quails Answer に 2 つの注意点があります。

ポイント1

これ

List<Cat> cats = Collections.checkedList(Cat.class, q.list());

これのはず

List<Cat> cats = Collections.checkedList(q.list(), Cat.class);

ポイント2

これから

List list = q.list();

これに

List<T> list = q.list();

元の返信タグ マーカーがブラウザによって取り除かれたことは明らかで、他の警告を減らすことができます。

于 2012-04-01T22:53:29.057 に答える
-1

これを試して:

Query q = sess.createQuery("from Cat cat");
List<?> results = q.list();
for (Object obj : results) {
    Cat cat = (Cat) obj;
}
于 2014-07-15T21:53:05.643 に答える
-1

hibernate クエリでタイプ セーフの警告を回避する良い解決策は、TorpedoQueryなどのツールを使用してタイプ セーフな hql を構築することです。

Cat cat = from(Cat.class);
org.torpedoquery.jpa.Query<Entity> select = select(cat);
List<Cat> cats = select.list(entityManager);
于 2015-11-11T18:54:00.337 に答える
-6

@SuppressWarnings("unchecked") を使用したくない場合は、次のことができます。

   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);
    }

参考までに、これを行う util メソッドを作成したので、コードが散らかることはなく、@SupressWarning を使用する必要もありません。

于 2008-09-22T16:34:04.643 に答える