【问题标题】:javax.persistence.NoResultException: getSingleResult() did not retrieve any entitiesjavax.persistence.NoResultException: getSingleResult() 没有检索到任何实体
【发布时间】:2011-02-06 11:21:24
【问题描述】:

我用 ejb 创建了一个命名查询来检查是否使用了用户名。 当 singleResult 为空时,我得到以下异常:

javax.persistence.NoResultException: getSingleResult() did not retrieve any entities

但这个例外是我在用户名空闲时想要的结果。

代码如下:

 public User getUserByUsername(String username) throws DAOException{
    try{
        Query q = em.createNamedQuery(User.getUserByUsername);
        q.setParameter("username", username);
        return (User) q.getSingleResult();
    }catch(Exception e){
        throwException(username, e);
        return null;
    }
}

有谁知道问题出在哪里。 :(

我想返回 null 并且不得到异常。

非常感谢

【问题讨论】:

    标签: java exception ejb


    【解决方案1】:

    您似乎使用语句throwException(username, e); 在您的catch 块中重新抛出异常。如果您希望毫无例外地获得用户或null,则应如下所示:

    public User getUserByUsernameOrNull(String username) {
        try{
            Query q = em.createNamedQuery(User.getUserByUsername);
            q.setParameter("username", username);
            return (User) q.getSingleResult();
        } catch(NoResultException e) {
            return null;
        }
    }
    

    【讨论】:

    • 完美。非常感谢。
    【解决方案2】:

    改用getResultList 并检查List 是否为空(元素为零)。否则,列表包含一个元素,您只需返回它。

    【讨论】:

    • 这应该是首选答案,因为它避免了异常处理块,在这种情况下,JPA 似乎强加给客户端。 blog.takipi.com/…
    • Guava 的 Iterables 类,特别是 getFirst 方法,展示了如何避免非异常情况的异常: getFirst '如果 iterable 为空,则返回 iterable 或 defaultValue 中的第一个元素。
    【解决方案3】:

    调用getSingleResult 时遇到定义的行为,但未找到任何条目:抛出NoResultException。您可以在 catch 子句中捕获 NoResultException,因为当 JPA 抛出 NoResultException 时,事务不会被标记为回滚。或者您可以使用 getResultList() 并检查大小是否正好为“1”,这样您就知道您已经找到了您的用户。

    此外,如果找不到用户,我不会返回“[null]”,而是抛出一个检查过的 UserNotFoundException(待定义)。但这取决于您要实现的方法的合同。

    【讨论】:

    • 您能否详细说明:“因为它是运行时异常,所以“捕获异常”不适合”.. 为什么不呢?
    【解决方案4】:

    Michael 说:“你可以在 catch 子句中捕获 NoResultException,因为当 JPA 抛出 NoResultException 时,事务不会被标记为回滚。”。看起来对于某些 jpa 实现,NoResultException 将 rollbak 事务,这违反了 jpa 规范,根据这篇文章:NoResultException marks transaction rollback

    【讨论】:

      【解决方案5】:

      如果您的应用程序使用 Spring Roo,则投票最多的答案不起作用:异常被方面捕获,您永远不会得到所需的 NoResultException。 解决该问题的唯一方法是使用 getResultList 并检查生成的 List 中的零个、一个或多个结果,如第二个投票最多的答案中所述。

      【讨论】:

        【解决方案6】:

        throwException 方法是做什么的?

        其中是否引发了异常,但您使用的是先前异常的消息?

        【讨论】:

          【解决方案7】:

          在 try-catch 块中捕获 NoResultException 并根据您的要求进行处理,例如返回 null 值。

          try-catch 的示例在以下链接中有详细说明: http://www.javabrahman.com/j2ee/jpa/no-result-exception/

          【讨论】:

            【解决方案8】:
            try {
                        Query queryObj = entityMgrObj
                                .createQuery("SELECT u FROM UserEntity u WHERE u.email = :email AND u.password = :password");
                        queryObj.setParameter("email", email);
                        queryObj.setParameter("password", password);
                        UserEntity userEntity = (UserEntity) queryObj.getSingleResult();
            
                        return userEntity;
            
                    } catch (NoResultException e) {
                        return null;
                    }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-01-30
              • 2015-09-14
              • 1970-01-01
              • 1970-01-01
              • 2014-10-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多