javax.persistence.Query.getResultList() 可以返回 null 吗?

Posted

技术标签:

【中文标题】javax.persistence.Query.getResultList() 可以返回 null 吗?【英文标题】:Can javax.persistence.Query.getResultList() return null? 【发布时间】:2010-11-10 01:42:36 【问题描述】:

如果是这样,在什么情况下?

Javadoc 和 JPA 规范什么也没说。

【问题讨论】:

我正在搜索这个问题!谢谢!最多 4 个你! 【参考方案1】:

如果规范说这不可能发生,你会相信吗?考虑到您的代码可能会在不同的 JPA 实现上运行,您会相信每个实现者都能做到吗?

无论如何,我都会进行防御性编码并检查是否为空。

现在有个大问题:我们是否应该将“null”和空列表视为同义词?这是规范应该帮助我们的地方,而不是。

我的猜测是 null 返回(如果确实可能发生)将等同于“我不理解查询”,而空列表将是“是的,理解查询,但没有记录”。

您可能有一个处理不可解析查询的代码路径(可能是一个异常),我倾向于在该路径下直接返回空值。

【讨论】:

+1 你说的太对了:“你会信任每个 JPA 提供商吗?”没有:) 编辑添加:Arthur 指出,如果没有找到记录,Hibernate 的 JPA 实际上会返回 null。所以实际上在这种情况下,我们确实需要将 null 和空列表折叠在一起。我相信我们上面经历的思考过程仍然有效。甚至可以想象,我们应该对不同的 JPA 堆栈有不同的 null 处理。欢迎来到便携乐趣。 同意。由于 JPA 规范没有做它应该做的事情,所以只存在“可移植性乐趣”......指定精确的语义。可惜它是由既得利益委员会管理的。 “我不懂查询”应该被处理为Exception,返回null,其中Collection是返回类型是一个明显的设计缺陷【参考方案2】:

你是对的。 JPA 规范对此只字未提。但是Java Persistence with Hibernate 一书,第 2 版说:

如果查询结果为空,则返回null

当您调用 query.getResultList() 没有结果时,Hibernate JPA 实现(实体管理器)返回 null。

更新

正如一些用户所指出的,似乎最新版本的 Hibernate 会返回一个空列表。

当没有找到结果时,Eclipselink 中也会返回一个空列表。

【讨论】:

这肯定过时了,Hibernate 返回一个空列表。 我仍然从 Hibernate 4.3.10 得到 null(作为 Spring Data 的 JPA 引擎运行)。这仅发生在单个本机查询中,因为典型的 JPA 查询按预期工作。 只需使用 OR 检查这两个条件。 if(rows == null || rows.size == 0) 其中 rows 是 getResultList() 返回的内容 只需将其包装在 Optional.ofNullable() 中即可。 我相信返回 null 而不是一个空列表不是规范的意图,否则它很清楚何时在其他地方期待 null。尤其是getResultList 的文档为Execute a SELECT query and return the query results as a(n) (un)typed List. - @return a list of the results。当然,我仍然会检查null,如果需要,我自己会返回一个空列表。【参考方案3】:

与 Arthur 的帖子相反,当我实际运行一个没有匹配实体的查询时,我得到一个空列表,而不是 null。这是使用 Hibernate,我认为这是正确的行为:当您要求实体集合但没有实体时,空列表是正确答案。

【讨论】:

对于 OpenJPA,我也得到一个空列表而不是 null。【参考方案4】:

当然,如果您使用 Jakarta 的 CollectionUtils.isNotEmpty 测试结果集,无论哪种方式都可以满足您的要求。

【讨论】:

【参考方案5】:

如果您仔细查看org.hibernate.loader.Loader (4.1),您会发现该列表始终在 processResultSet() 方法中进行初始化(doc、source)。

protected List processResultSet(...) throws SQLException 
   final List results = new ArrayList();

   handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session );
   ...
   return results;


所以我认为它现在不会返回 null。

【讨论】:

为确切的代码 sn-p 干杯。但是这个答案只关注休眠,这是规范的实现之一。 OpenJPA 等其他实现在行为上有所不同。此外,hibernate 似乎改变了不同版本的行为。【参考方案6】:

Query.getResultList() 返回一个空列表,而不是 null。所以检查返回结果中的isEmpty(),如果为假则继续其余逻辑。

【讨论】:

【参考方案7】:

鉴于getResultsList()org.hibernate.ejb.QueryImpl 类中的实现,有可能返回一个null

public List getResultList() 
    try 
        return query.list();
    
    catch (QueryExecutionRequestException he) 
        throw new IllegalStateException(he);
    
    catch( TypeMismatchException e ) 
        throw new IllegalArgumentException(e);
    
    catch (HibernateException he) 
        em.throwPersistenceException( he );
        return null;
    

我的休眠版本是:3.3.1.GA

【讨论】:

以上是关于javax.persistence.Query.getResultList() 可以返回 null 吗?的主要内容,如果未能解决你的问题,请参考以下文章