javax.persistence.NoResultException:找不到查询的实体

时间:2011-11-15 15:08:52

标签: java hibernate jpa exception-handling null

在我发布这个问题之前,我已经看了this,但我无法得到我想要的东西。

我知道对于我写的查询,可能只存在一行或根本没有。所以,我没有理由使用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,我只是想更新它

有一种方法可以解决这个问题,我认为这不是正确的方法。它是:我将有一个try-catch块,如果它抛出异常,我可以写入将新数据插入到catch块上的DB中。但我相信会有更好的方法。

6 个答案:

答案 0 :(得分:77)

是。您需要使用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..
}

答案 1 :(得分:16)

使用java 8时,您可以利用流API并简化代码

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

这将为您提供java.util.Optional

如果您更喜欢null,那么您需要的只是

 ...
.getResultList()
.stream().findFirst().orElse(null);

答案 2 :(得分:7)

你提到从查询中获取结果列表,因为你不知道有一个UniqueResult(因此例外)你可以使用list并检查大小吗?

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

由于你没有使用get()来获取你的唯一对象,无论你调用uniqueResult还是list,都会执行查询。

答案 3 :(得分:3)

如果您不知道是否有任何结果,请使用getResultList()

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

答案 4 :(得分:0)

另一种选择是使用uniqueResultOptional()方法,该方法在结果中为“可选”:

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

Optional<DrawUnusedBalance> drawUnusedBalance=query.uniqueResultOptional();

答案 5 :(得分:0)

String hql="from DrawUnusedBalance where unusedBalanceDate= :today";
DrawUnusedBalance drawUnusedBalance = em.unwrap(Session.class)
    .createQuery(hql, DrawUnusedBalance.class)
    .setParameter("today",new LocalDate())
    .uniqueResultOptional()
    .orElseThrow(NotFoundException::new);