皆さん、こんにちは。永続性/休止状態に慣れていないので、あなたの助けが必要です。
これが状況です。いくつかのものを含むテーブルがあります。それらを人と呼びましょう。そのテーブルにあるデータベースからすべてのエントリを取得したいのですが。
テーブルの各列(名前、年齢など)のプロパティを持つ単純なPOJOであるPersonクラスがあります。
ここに私が持っているものがあります:
Query lQuery = myEntityManager.createQuery("from Person")
List<Person> personList = lQuery.getResultList();
ただし、これはList
からList<Person>
への未チェックの変換であるという警告が表示されます
私は単にコードを
Query lQuery = myEntityManager.createQuery("from Person")
List<Person> personList = (List<Person>)lQuery.getResultList();
動作しますが、動作しません。
これを行う方法はありますか?永続化により、クエリの戻り値の型を設定できますか? (多分ジェネリックスを通して?)
JPAの初心者はこれを決定的な答えとして取り上げていましたが、次の質問でより良いものを見つけました: JPA EntityManagerクエリでNoResultExceptionがスローされるのになぜ見つからないのですか?
クエリの代わりにTypedQueryを使用するのと同じくらい簡単です。例:
TypedQuery<Person> lQuery = myEntityManager.createQuery("from Person", Person.class);
List<Person> personList = lQuery.getResultList();
注:この回答はJPA 2.0の時点で古くなっているため、予想されるタイプを指定できます。 この答え を参照してください。
警告を抑制する
@SuppressWarnings("unchecked")
List<MyType> result = (List<MyType>) query.getResultList();
私が今まで見たこの問題の唯一の解決策です。抑制は醜いですが、JPAが正しいタイプのオブジェクトを返すと信頼できるため、手動でチェックする必要はありません。
ポリモーフィズムを使用していて、正確な結果の型がわからない場合は、Class
パラメーターが制限されたジェネリックスの使用も一般的なパターンです。
public List<T extends MyBaseType> findMyType(Class<T> type) {
@SuppressWarnings("unchecked")
List<T> result = (List<T>) this.entityManager.createQuery(
"FROM " + type.getName())
.getResultList();
return result;
}
Javaコレクションクラスソリューションがありますが、キャストが失敗した方法、または警告を発しているだけの場合は説明しませんでした...
これはこれを検証する1つの方法です。
Collections.checkList(lQuery.getResultList(), Person.class);
しかし、それを検証する必要がない場合:
@SuppressWarnings("unchecked") List<Person> personList = lQuery.getResultList();
別の方法:
Query query = entityManager.createNativeQuery("SELECT * FROM person", Person.class);
List<Person> rows = query.getResultList();
私もしばらくの間、この問題に悩まされてきました。リストを繰り返し処理して確認することもできますが、ノイズは少ない方がいいと思います。私がこれを回避するのを見た最短の方法は警告を沈黙させることですが、私もそれに非常に不快です。他の解決策を見てみたいです。
@SuppressWarnings("unchecked")
List<Person> personList = lQuery.getResultList();
うーん、調べていると、Java.netで興味深い post が見つかりました。ユーザーのコメントは特に興味深いものでした。