web-dev-qa-db-ja.com

javax.persistence.NoResultException:クエリのエンティティが見つかりません

この質問を投稿する前に、私はすでに this を見ていましたが、探していたものを得ることができませんでした。

私が書いたクエリでは、1行しか存在しないか、まったく存在しないことがあります。したがって、getResultList()を使用する理由はありません。

ここに私のコードがあります:

String hql="from DrawUnusedBalance where unusedBalanceDate= :today";
Query query=em.createQuery(hql);
query.setParameter("today",new LocalDate());

DrawUnusedBalance drawUnusedBalance= 
    (DrawUnusedBalance)query.getSingleResult();// we can have only a
                                               // single datum per day
//`System.out.println(drawUnusedBalance.toString());`

問題は、行がない場合は例外をスローし、そうでない場合は正常に動作することです。私は問題を知っていますが、最良の解決策も探しています。

私が望んでいたのは、DBに行がなければ(例外を取得するのではなく)nullオブジェクトを取得したいので、新しいデータを挿入し、nullでない場合は単に更新したいだけです。

これを処理する方法は1つありますが、これは正しい方法ではないと考えています。それは:try-catchブロックがあり、例外がスローされた場合、catchブロックのDBに新しいデータを挿入するために書き込むことができます。しかし、もっと良い方法があると信じています。

44
WowBow

はい。 try/catchブロックを使用する必要がありますが、Exceptionをキャッチする必要はありません。 [〜#〜] api [〜#〜] に従って、結果がない場合はNoResultExceptionをスローします。処理方法

DrawUnusedBalance drawUnusedBalance = null;
try{
drawUnusedBalance = (DrawUnusedBalance)query.getSingleResult()
catch (NoResultException nre){
//Ignore this because as per your logic this is ok!
}

if(drawUnusedBalance == null){
 //Do your logic..
}
79
ManuPK

Java 8を使用すると、ストリームAPIを利用してコードを単純化できます。

return (YourEntityClass) entityManager.createQuery()
....
.getResultList()
.stream().findFirst();

これにより、Java.util.Optionalが得られます。

代わりにnullを好む場合、必要なのは

 ...
.getResultList()
.stream().findFirst().orElse(null);
16
Bartosz Bilicki

クエリから結果リストを取得することについて言及しましたが、リストを使用してサイズを確認できるUniqueResult(したがって例外)があることを知らないのですか?

if (query.list().size() == 1) 

一意のオブジェクトを取得するためにget()を実行していないため、uniqueResultまたはlistのどちらを呼び出してもクエリが実行されます。

7
Alex Barnes

結果があるかどうかわからない場合は、getResultList()を使用します。

List<User> foundUsers = (List<User>) query.getResultList();
        if (foundUsers == null || foundUsers.isEmpty()) {
            return false;
        }
User foundUser = foundUsers.get(0);
3
ACV