【问题标题】:NoResultException: getSingleResult() did not retrieve any entities. QueryImpl.throwNoResultExceptionNoResultException:getSingleResult() 没有检索到任何实体。 QueryImpl.throwNoResultException
【发布时间】:2017-12-22 09:38:36
【问题描述】:

我们在 payara 164 应用服务器中部署了一个 java web 应用程序。
主机是 debian 9.3 服务器,使用的数据库是 mariadb-server-10.1,java 版本是“1.8.0_131”。

最近我们面临着一些问题,其中包括以下问题。它只是一个实例,因为它与许多其他对象随机发生,即使它们确实不是 NULL 而是正确填充。

javax.ejb.EJBTransactionRolledbackException 在 dmlm.models.entities.User.getCustomer(User.java:337) 原因:javax.persistence.NoResultException: getSingleResult() 没有检索到任何实体。

编辑:

在几个地方调用如下方法:

public Customer getCustomerByUser(User user)
{
    TypedQuery<Customer> q = em.createNamedQuery("Customer.findByUser", Customer.class);
    q.setParameter("userId", user.getId());
    if (LOG.isLoggable(Level.FINER)) {
        //<editor-fold defaultstate="collapsed" desc="per stampare nei log una query runtime">
        org.eclipse.persistence.sessions.Session session
                = em.unwrap(JpaEntityManager.class).getActiveSession();
        DatabaseQuery databaseQuery = ((EJBQueryImpl) q).getDatabaseQuery();
        databaseQuery.prepareCall(session, new DatabaseRecord());
        DatabaseRecord recordWithValues = new DatabaseRecord();
        recordWithValues.add(new DatabaseField("userId"), user.getId());

        String sqlStringWithArgs
                = databaseQuery.getTranslatedSQLString(session, recordWithValues);
        LOG.finest(sqlStringWithArgs);
        //</editor-fold>
    }
    return q.getSingleResult();
}

日志部分只是打印出使用参数创建的真实查询

命名查询:

@NamedQuery(name = "Customer.findByUser",
            query = "SELECT m FROM Customer m JOIN m.users us WHERE m.deleted = false AND us.id = :userId")

如前所述,结果应该是带有客户 ID 的单个结果

编辑 2: 我们尝试将数据库从 maria-db 更改为 mysql,但没有成功

【问题讨论】:

  • 创建和执行查询的代码在哪里?调试在哪里,参考 JPA 提供者日志?

标签: jpa


【解决方案1】:

只有在您 100% 确定数据库中存在特定记录(唯一)时才应使用getSingleResult()。抛出的异常是运行时。运行时异常 = 程序员问题。

如果您不知道记录是否唯一存在,您可以使用此构造。

public Entity getEntityByName(String name) {
    TypedQuery<Entity> query = em.createNamedQuery(Entity.GET_ENTITY_BY_NAME, Entity.class);
    query.setParameter(Entity.PRM_NAME, name);
    List<Project> found = query.getResultList();

    if (found.isEmpty()) {
        return null; //or throw checked exception data not found
    } else {
        return found.get(0);
    }

}

【讨论】:

  • 实际上,我敢说您应该独家使用getSingleResult() 进行单一结果聚合查询。单一结果既不是“单一或无”结果,也不是“单一或多个”结果。
  • 问题是结果查询应该填充单个结果。有时候,正常返回单个结果的记录,返回一个空结果(那是不可能的)
  • 有人知道吗?
猜你喜欢
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多