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 吗?的主要内容,如果未能解决你的问题,请参考以下文章