Javax.persistence.NoResultException: объект не найден для запроса
Прежде чем я разместил этот вопрос, я уже посмотрел этот, но я не мог получить то, что искал.
Я знаю, что для запроса, который я написал, может существовать только одна строка или вообще ничего. Поэтому нет смысла использовать 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());`
Проблема заключается в том, что если нет строки, она генерирует исключение, и если она не работает, это нормально. Я знаю проблему, но я также ищу лучшее решение.
То, что я хотел, если в базе данных нет строки, я хотел бы получить нулевой объект (вместо получения исключения), поэтому я буду вставлять новые данные, если он не является нулевым, я просто хочу его обновить.
Есть один способ справиться с этим, и я считаю, что это не правильный способ сделать это. Это: у меня будет блок try-catch, и если он выдаст исключение, я могу написать, чтобы вставить новые данные в базу данных в блоке catch. Но я верю, что будет лучший способ.
Ответы
Ответ 1
Да. Вам нужно использовать блок 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..
}
Ответ 2
Вы упомянули получение списка результатов из запроса, так как вы не знаете, что есть UniqueResult (отсюда исключение), вы можете использовать список и проверить размер?
if (query.list().size() == 1)
Поскольку вы не используете get() для получения своего уникального объекта, запрос будет выполнен, если вы вызываете uniqueResult или список.
Ответ 3
При использовании java 8 вы можете воспользоваться потоковым API и упростить код для
return (YourEntityClass) entityManager.createQuery()
....
.getResultList()
.stream().findFirst();
Это даст вам java.util.Optional
Если вы предпочитаете нуль, все, что вам нужно, это
...
.getResultList()
.stream().findFirst().orElse(null);
Ответ 4
Если вы не знаете, есть ли какие-либо результаты, используйте getResultList()
.
List<User> foundUsers = (List<User>) query.getResultList();
if (foundUsers == null || foundUsers.isEmpty()) {
return false;
}
User foundUser = foundUsers.get(0);