org.hibernate.NonUniqueResultException: 查询未返回唯一结果:2

77

我在我的DAO中有以下代码:

String sql = "SELECT COUNT(*) FROM CustomerData " +
             "WHERE custId = :custId AND deptId = :deptId";
Query query = session.createQuery(sql);
query.setParameter("custId", custId);
query.setParameter("deptId", deptId);
long count = (long) query.uniqueResult(); // ERROR THROWN HERE

在标记的行,Hibernate 抛出了以下异常:

org.hibernate.NonUniqueResultException: 查询没有返回唯一结果:

我不确定发生了什么,因为 count(*) 总是只会返回一行。

而且当我直接在数据库上运行此查询时,它将返回结果为 1。那问题是什么呢?


9
问题在于你要求一个 uniqueResult,这意味着只能返回一行结果,但查询却找到了多个结果。 - Stultuske
7
但是count(*)总是只会返回1行。 - user3198603
我刚刚告诉你什么会触发NonUniqueResultException异常。我同意对于计数来说这很奇怪,但还是可以尝试去掉UniqueResult约束条件吗? - Stultuske
2
@user3198603,你解决了这个问题吗?你找到问题的原因了吗? - cнŝdk
如果您的查询结果有多行记录,应该使用NHibernate.IQuery.ListAsync而不是UniqueResultAsync。 - peter70
显示剩余4条评论
16个回答

48

看起来你的查询返回了多个结果,请检查数据库。在 query.uniqueResult() 的文档中,你可以阅读到:

抛出:org.hibernate.NonUniqueResultException - 如果有多个匹配结果

如果你想避免这个错误并仍然使用唯一结果请求,你可以使用这种解决方法:query.setMaxResults(1).uniqueResult();


26

Hibernate 可选地按照createTime倒序查找clientId和status匹配的第一个结果。

“findTop”!!仅返回一个结果!


23

我认为其他答案没有解释关键部分:为什么"COUNT(*)"返回多个结果?

我今天遇到了同样的问题,发现如果你有另一个类扩展目标映射类(这里是"CustomerData"),Hibernate会进行此操作。

希望这能为其他不幸的人节省一些时间。


1
这应该是被接受的答案。而且计数总是返回1,没有任何借口。 - Al Kasih
1
这应该是被接受的答案。Hibernate 可能正在使用 CustomerData 类和其子类进行 UNION 操作。 - Lluis Martinez

13
通常情况下,当查询结果(在您的情况下存储在一个对象中)无法转换为所需的对象时,Oracle会抛出此异常。例如,当结果是一个

时。
List<T>

你将结果放入单个 T 对象中。

如果出现长整型转换错误,除了建议使用包装类使其所有列都能表现一致,我认为事务或查询本身的问题也可能导致此问题。


这是答案! - გენო მუმლაძე

7
这意味着你编写的查询语句返回了多个元素(结果),而你的代码期望只返回单个结果。

1
我已找到问题的核心:

如果查询中包含 GROUP BY 语句,SELECT COUNT(*) 的结果可能是一个列表,

有时候 Hibernate 会为了好玩而重写你的 HQL 并将 GROUP BY 加入其中。


1
我正在使用JPQL并希望返回Map。在我的情况下,原因是我想获得Map ,但必须期望List > :)

1

请检查您的表格,看看是否有一个实体出现了多次。

我也遇到了同样的错误,数据如下:

id amount clientid createdate expiredate
428 100 427 19/11/2021 19/12/2021
464 100 459 22/11/2021 22/12/2021
464 100 459 22/11/2021 22/12/2021

在这里,您可以看到clientid与464出现了两次。

我通过删除一行来解决这个问题:

id amount clientid createdate expiredate
428 100 427 19/11/2021 19/12/2021
464 100 459 22/11/2021 22/12/2021

1

在未完成的事务期间,您的应用程序是否尝试使用与您正在使用的标识符重复的字段创建实体,从而可能引发此异常?

在这种情况下,由于事务不会被提交到数据库中,因此新的(重复)实体将不会在数据库中可见。但是,异常仍将被抛出。


1
收到这个错误时,正在执行正确的Hibernate查询。问题在于当一个类继承另一个类时,Hibernate会将两个类一起计算。通过向存储库类添加一个方法,可以“修复”此错误。通过覆盖类计数,您可以手动确定计数方式。
@Override 
public Integer count(Page<MyObject> page) {
   // manual counting method here
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接