はじめに
JPAを使っていると、1件だけデータを取得したい場面で
query.getSingleResult()
ではなく、
query.getResultList().get(0)
というコードを見かけることがあります。
「getSingleResult() という便利なメソッドがあるのに、なぜあえて getResultList() を使うの?」
そんな疑問から、両者の違いと使い分けについてまとめてみました。
それぞれの特徴
getSingleResult()
- 戻り値:
Object
(もしくはクエリの型に応じた型) - 想定:結果が1件ちょうどであること
- 主な例外:
-
NoResultException
(結果が0件) -
NonUniqueResultException
(結果が2件以上)
-
try {
Object result = query.getSingleResult();
} catch (NoResultException | NonUniqueResultException e) {
// 例外処理
}
※ 注意点
例外が発生しやすく、「1件しか返らない」ことが保証されていないと使いにくい。
getResultList()
- 戻り値:
List<Object>
- 想定:結果が0件、1件、複数件のどれでもOK
- 主な例外:特になし(SQLエラーなどの根本的な問題以外)
List<Object> results = query.getResultList();
if (!results.isEmpty()) {
Object first = results.get(0);
}
☑️ メリット
- 柔軟性が高く、例外処理がいらない
- 複数件返ってもとりあえず1件目を取得できる
なぜ getResultList().get(0) を使うのか?
getSingleResult()
を使うと、結果が0件や複数件でもすぐ例外になるため、現場では敬遠されがちです。
一方で getResultList()
は以下のようなメリットがあります。
比較項目 | getSingleResult() | getResultList().get(0) |
---|---|---|
0件の場合 | NoResultException |
IndexOutOfBoundsException (※) |
複数件の場合 | NonUniqueResultException |
OK(先頭のみ取得) |
柔軟性 | 低い | 高い |
使いやすさ | 例外処理が必須 | 結果チェックで対応可能 |
※ getResultList().get(0)
の場合も、リストが空なら IndexOutOfBoundsException
が起きるので注意!
実務での使い分け指針
getSingleResult() を使うべきケース
- テーブル定義やロジック的に 絶対に1件返る ことが保証されている
- 例外を明確にハンドリングしたい(意図的に NoResultException を使いたい 等)
getResultList() を使うべきケース
- 0件や複数件返る可能性 がある
- データ件数に柔軟に対応したい
- 例外処理を避けたい or 面倒な try-catch を書きたくない
おわりに
今回は、SELECT結果を取得する2つのメソッドの違いと用法について調べてみました。
getSingleResult()
を使用しないでgetResultList().get(0)
を使用する理由について、理解していただけましたでしょうか。
私と同じ疑問を抱いた人の解消記事となっていただければ幸いです。