【问题标题】:org.hibernate.NonUniqueResultException: query did not return a unique result: 2?org.hibernate.NonUniqueResultException:查询没有返回唯一结果:2?
【发布时间】:2014-07-15 00:37:04
【问题描述】:

我的 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(*) 将始终只返回一行。

另外,当我直接在 db 上运行此查询时,它返回结果为 1。那么问题是什么?

【问题讨论】:

  • 问题是你要求一个uniqueResult,这意味着可能只有一行返回,但查询找到了多个结果。
  • 但 count(*) 将始终只返回 1 行
  • 我刚刚告诉过你是什么触发了 NonUniqueResultException。我同意计数这很奇怪,但仍然如此。你试过没有 UniqueResult 约束吗?
  • 什么是客户数据?抽象类?
  • @user3198603 你解决了这个问题吗?你找到问题的原因了吗?

标签: java hibernate hql jpql dao


【解决方案1】:

您的查询似乎返回了多个结果,请检查数据库。在query.uniqueResult() 的文档中,您可以阅读:

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

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

【讨论】:

    【解决方案2】:

    休眠 可选的 findTopByClientIdAndStatusOrderByCreateTimeDesc(Integer clientId, Integer status);

    “找顶”!!唯一的结果!

    【讨论】:

      【解决方案3】:

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

      我今天也遇到了同样的问题,我发现如果你有另一个类扩展目标映射类(这里是“CustomerData”),Hibernate 会做到这一点。

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

      【讨论】:

      • 这应该是公认的答案。并且 count 总是返回 1,没有任何借口。
      【解决方案4】:

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

      List<T>
      

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

      在转换为长错误的情况下,除了建议使用包装类以使所有列的行为相同外,我猜事务或查询本身的问题会导致此问题。

      【讨论】:

      • 就是答案!
      【解决方案5】:

      这意味着您编写的查询返回多个元素(结果),而您的代码需要一个结果。

      【讨论】:

        【解决方案6】:

        在执行其他正确的休眠查询时收到此错误。问题是当一个类扩展另一个休眠时,两者都计算在内。可以通过向存储库类添加方法来“修复”此错误。

        通过覆盖类计数,您可以手动确定计数方式。

        @Override 
        public Integer count(Page<MyObject> page) {
           // manual counting method here
        }
        

        【讨论】:

          【解决方案7】:

          我找到了问题的核心:

          SELECT COUNT(*)的结果可以是一个列表,如果查询中有GROUP BY,

          有时 Hibernate 会重写您的 HQL 并将 GROUP BY 放入其中,只是为了好玩。

          【讨论】:

            【解决方案8】:

            基本上,您的查询会返回多个结果集。 在 API Docs uniqueResult() 方法中说 返回匹配的单个实例的便捷方法 查询,如果查询没有返回结果,则返回 null

            uniqueResult() 方法只产生单个结果集

            【讨论】:

              【解决方案9】:

              在未完成事务期间是否会引发此异常,您的应用程序正在尝试创建一个实体,该实体具有与您用来尝试查找单个实体的标识符的重复字段?

              在这种情况下,新的(重复的)实体将在数据库中不可见,因为事务不会,并且永远不会提交到数据库。但是仍然会抛出异常。

              【讨论】:

                【解决方案10】:

                认为这可能对某人有所帮助,因为“当数据查询的数量大于 1 时”。reference

                【讨论】:

                  【解决方案11】:

                  正如 Ian Wang 所说,我怀疑您使用的是 spring 的存储库。几天前,您只是复制过去的一个课程,并在它最终未使用时忘记将其删除。检查该存储库,并查看您使用的是否有多个相同类别的表。计数不是行数,而是表问题的计数。

                  【讨论】:

                    【解决方案12】:

                    我使用的是 JPQL,想返回 Map。就我而言,原因是我想得到Map&lt;String, String&gt;,但又不得不期待List&lt;Map&lt;String, String&gt;&gt; :)

                    【讨论】:

                      【解决方案13】:

                      这意味着 orm 技术没有预先编程为您提供您正在寻找的结果,因为数据库中有太多相同的结果。例如,如果我的数据库中有多个相同的值并且我想取回它,那么您将遇到选择查询时遇到的错误。

                      【讨论】:

                      • 您的帖子无法阅读,但似乎是在尝试回答这个问题。我建议edit 在更流利的人的帮助下根据How to Answer 改进这一点。
                      【解决方案14】:

                      检查您的表格,其中一个实体多次出现。

                      我有同样的错误,这个数据:

                      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

                      【讨论】:

                        【解决方案15】:

                        首先你必须测试查询列表的大小;这里是一个例子:

                        long count;
                        if (query.list().size() > 0)
                            count=(long) criteria.list().get(0);   
                        else
                            count=0;            
                        return count;
                        

                        【讨论】:

                          猜你喜欢
                          • 2015-10-30
                          • 2018-06-04
                          • 2020-10-15
                          • 2020-06-05
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2020-09-09
                          • 1970-01-01
                          相关资源
                          最近更新 更多