【问题标题】:javax.persistence.NoResultException: No entity found for queryjavax.persistence.NoResultException:未找到查询的实体
【发布时间】:2011-11-15 15:08:51
【问题描述】:

在我发布这个问题之前,我已经查看了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());`

问题是,如果没有行,它会抛出异常,如果没有,它可以正常工作。我知道这个问题,但我也在寻找最好的解决方案。

我想要的是,如果数据库中没有行,我想获取一个空对象(而不是获取异常),所以我将插入一个新数据,如果它不为空,我只想更新它.

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

【问题讨论】:

    标签: java hibernate jpa exception-handling null


    【解决方案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..
    }
    

    【讨论】:

    • 谢谢 ManuPK ...但是我仍然需要编写一些代码来创建一个对象并在 Catch 块中坚持做一个 DB .... 我认为这不是一个好从 catch 块中持久化数据的方法......尽管 tnx 为您的响应。
    • 我觉得捕获已检查异常并采取替代路径并没有错。这就是 JPA 为您提供如何处理它的选项的原因。实际上,您正在寻找的方法在 hibernate 中可用,而 JPA 没有。
    • @user1017111 我遇到了您在 catch 中编写代码时遇到的问题。我已经稍微更新了答案以使代码可读。
    • 有趣的是,这里讨论了这个解决方案:stackoverflow.com/questions/2002993/jpa-getsingleresult-or-null
    • @ManuPK : javax.persistence.NoResultException 未检查异常。其未经检查的异常。
    【解决方案2】:

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

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

    这会给你 java.util.Optional

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

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

    【讨论】:

    • 问题与getSingleResult()有关,与.getResultList()无关。甚至在描述中都有说明。
    • 他仍然从getResultList() 中获取一个元素。
    【解决方案3】:

    另一种选择是使用 uniqueResultOptional() 方法,它会在结果中为您提供可选:

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • 现在,我正在使用 query.list().isEmpty() 来查看是否有任何数据返回......我认为如果我们得到一个 null 对程序员来说会很容易像 get() 方法这样的对象。谢谢
      • 没问题。 IsEmpty 显然是我写答案时的意思;)
      • @Alex:这种方法的唯一问题是您需要使用附加查询来获取计数。这可能是性能开销。
      • 为什么需要额外的查询来获取计数?您已经获得了一个列表,其中包含与查询匹配的所有实体。
      • @Alex:好的。然后 query.list() 应该分开存储和检查。我明白你的意思,你是对的。我对 if 条件感到困惑。
      【解决方案5】:

      当你不知道有没有结果时,使用getResultList()

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

      【讨论】:

      • 好的,这是一个建议而不是答案。但可能对其他人有用。
      • 不知道有没有结果时,使用getResultList()。 List&lt;User&gt; foundUsers = (List&lt;User&gt;) query.getResultList(); if (foundUsers == null || foundUsers.isEmpty()) { return false; } User foundUser = foundUsers.get(0);
      • 这看起来更糟,不是吗?
      【解决方案6】:
      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);
      

      【讨论】:

        猜你喜欢
        • 2014-10-26
        • 2015-09-14
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 2011-02-06
        • 1970-01-01
        • 2011-09-04
        • 2023-03-08
        相关资源
        最近更新 更多