【问题标题】:Spring Data JPA return wrong totalElement count after group bySpring Data JPA在分组后返回错误的totalElement计数
【发布时间】:2020-03-16 01:25:08
【问题描述】:

我是 Spring Data JPA 的新手,并且有以下内容

        Page<Object> page = tableARepository.findAll(
                (root, criteriaQuery, criteriaBuilder) -> criteriaQuery
                        .where(sortConfig.getPredicateList(root, criteriaQuery, criteriaBuilder))
                        .groupBy(root.get("colB"))
                        .getRestriction(),
                sortConfig.getPageable()
        );

一切都是正确的,除了page.getTotalElements() 返回错误的计数,我还发现它返回的计数没有groupBy

我需要page.getTotalElements() 来显示前端的总行数,目前的解决方法是我重新查询它并获取结果的大小,这不是很漂亮的事情(该网站仍处于开发阶段)。

我还打印出了休眠 sql 查询,并且选择计数查询确实包含 groupBy,但我不确定是什么导致它返回错误值。

假设,tableA的数据如下:

ColA  | ColB | ...
1       A
2       B
3       B
4       C
5       D

groupBy之后 我应该有下面的结果和计数

ColA  | ColB | ...
1       A
2       B
4       C
5       D

总数:4

但不知怎的,我得到了 5,有人可以帮忙吗?

注意:SortConfig 由我的同事开发,用于分页。

编辑:

select
    count(tblA_.tableA_ID) as col_0_0_ 
from
    tableA tblA_ 
where
    tblA_.tableAColC like ? 
group by
    tblA_.tableAColB

【问题讨论】:

  • 你能用hibernate生成的sql查询更新问题吗
  • 还有 5 个计数是什么意思?你可以发布它返回的结果集吗?也许它只是一个数据问题?
  • @AntJavaDev 我做了一个 where ColC like abc 将返回 43 行和 43 个计数,之后我添加了一个 groupBy colB 它将返回 33 行和 43 个计数。
  • 哦,现在我明白你的问题了!?!除了这两个链接herehere 之外,无法猜测其他任何内容,作为一种解决方案,我建议使用本机查询或原始 JPA 查询(不是标准之一)并从结果集中获取总数,而不是从分页元素,检查这个answer。同样作为 2 个链接的参考,您使用的是哪个 spring 数据版本?
  • @AntJavaDev 是的!这就是我目前面临的。所以这是一个错误,感谢您提供的链接,我将检查这些链接。我正在使用 spring data jpa 2.1.10.RELEASE 和 spring boot 2.1.8.RELEASE。

标签: java spring-data-jpa spring-data


【解决方案1】:

使用@EnableJpaRepositories 来定义repositoryBaseClass,我在子包的config 类中做了。

    @Configuration
    @EnableJpaRepositories(
            repositoryBaseClass = SimpleJpaRepositoryEvenForGroupBy.class,
            value = "com.company.repository"
    )
    public class JpaConfig {
    }

编写你自己的 executeCountQuery

    /**
     * A SimpleJpaRepository where COUNT returns the right number of rows even for GROUP BY queries.
     */
    public class SimpleJpaRepositoryEvenForGroupBy<T, ID> extends SimpleJpaRepository<T, ID> {
    
        public SimpleJpaRepositoryEvenForGroupBy(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
            super(entityInformation, entityManager);
        }
    
        public SimpleJpaRepositoryEvenForGroupBy(Class<T> domainClass, EntityManager em) {
            super(domainClass, em);
        }
    
        /**
         * Exactly the same method as in SimpleJpaRepository, but this calls the executeCountQuery of this class
         */
        @Override
        protected <S extends T> Page<S> readPage(TypedQuery<S> query, final Class<S> domainClass, Pageable pageable,
                                                 @Nullable Specification<S> spec) {
    
            if (pageable.isPaged()) {
                query.setFirstResult((int) pageable.getOffset());
                query.setMaxResults(pageable.getPageSize());
            }
    
            return PageableExecutionUtils.getPage(query.getResultList(), pageable,
                    () -> executeCountQuery(getCountQuery(spec, domainClass)));
        }
    
        /**
         *  An executeCountQuery where COUNT returns the right number of rows even for GROUP BY queries.
         */
        private static long executeCountQuery(TypedQuery<Long> query) {
            Assert.notNull(query, "TypedQuery must not be null!");
    
            List<Long> resultList = query.getResultList();
            if (resultList.size() == 1) {
                return resultList.get(0);
            }
    
            return resultList.size();
        }
    }

【讨论】:

    【解决方案2】:

    根据@AntJavaDev的评论,确认是Pageable中的一个bug。

    现在我改为使用找到here 的PageImpl 方法,效果很好。

    【讨论】:

      【解决方案3】:

      检查您的可分页对象是否从零开始索引。类似的东西:

      Pageable pageable = new PageRequest(pageId-1, size); 
      

      【讨论】:

      • 检查 sortConfig 的实现。这就是问题所在。如果您可以粘贴与分页有关的课程部分。
      猜你喜欢
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2015-09-09
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      相关资源
      最近更新 更多