jpa group by 统计总数错误

一 先说问题

手写specification时,如果group by且分页,那么获得的总数总是大于实际(group by后的)总数。

二 原因

//源码在这个类里

package org.springframework.data.jpa.repository.support; public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

@Override
public Page&lt;T&gt; findAll(@Nullable Specification&lt;T&gt; spec, Pageable pageable) {

	TypedQuery&lt;T&gt; query = getQuery(spec, pageable);
	return isUnpaged(pageable) ? new PageImpl&lt;T&gt;(query.getResultList())
			: readPage(query, getDomainClass(), pageable, spec);
}

protected &lt;S extends T&gt; Page&lt;S&gt; readPage(TypedQuery&lt;S&gt; query, final Class&lt;S&gt; domainClass, Pageable pageable,
		@Nullable Specification&lt;S&gt; spec) {

	if (pageable.isPaged()) {
		query.setFirstResult((int) pageable.getOffset());
		query.setMaxResults(pageable.getPageSize());
	}

	return PageableExecutionUtils.getPage(query.getResultList(), pageable,
			() -&gt; executeCountQuery(getCountQuery(spec, domainClass)));
}

private static long executeCountQuery(TypedQuery&lt;Long&gt; query) {

	Assert.notNull(query, "TypedQuery must not be null!");

	List&lt;Long&gt; totals = query.getResultList();
	long total = 0L;

//group 后每条记录的重复次数 它给加起来了,所以我们获得的统计数总是大于实际 for (Long element : totals) { total += element == null ? 0 : element; }

	return total;
}

}

 

三 解决办法--继承SimpleJpaRepository类重写findAll方法:

public class MySimpleJparepository<T,ID extends Serializable> extends SimpleJpaRepository <T,Serializable>{
public MySimpleJparepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
}

public MySimpleJparepository(Class&lt;T&gt; domainClass, EntityManager em) {
    super(domainClass, em);
}

@Override
public Page&lt;T&gt; findAll(Specification&lt;T&gt; spec, Pageable pageable) {

    TypedQuery&lt;T&gt; query = getQuery(spec, pageable);
    return isUnpaged(pageable) ? new PageImpl&lt;T&gt;(query.getResultList())
            : readPage(query, getDomainClass(), pageable, spec);
}
private static boolean isUnpaged(Pageable pageable) {
    return pageable.isUnpaged();
}
protected &lt;S extends T&gt; Page&lt;S&gt; readPage(TypedQuery&lt;S&gt; query, final Class&lt;S&gt; domainClass, Pageable pageable,
                                         @Nullable Specification&lt;S&gt; spec) {

    if (pageable.isPaged()) {
        query.setFirstResult((int) pageable.getOffset());
        query.setMaxResults(pageable.getPageSize());
    }

    return PageableExecutionUtils.getPage(query.getResultList(), pageable,
            () -&gt; executeCountQuery(getCountQuery(spec, domainClass)));
}
private static long executeCountQuery(TypedQuery&lt;Long&gt; query) {

    Assert.notNull(query, "TypedQuery must not be null!");

    List&lt;Long&gt; totals = query.getResultList();

//把加起来的逻辑给去掉 return totals.size(); } }

四 启动类加注解注入我们新的实现类

@EnableJpaRepositories(repositoryBaseClass = MySimpleJparepository.class)

不过还没找到它这加起来的目的是什么。。。淦 好像还是有点不放心

...