DATAJPA-257 - Make count query execution in SimpleJpaRepository more robust.
The execution of a count query can potentially return multiple values instead of just a single one. This causes persistence providers to throw an exception as we trigger ….getSingleResult() in SimpleJpaRepository. We're now calling …getResultList() and sum up all values returned.
This commit is contained in:
@@ -97,6 +97,7 @@ public abstract class JpaQueryExecution {
|
||||
|
||||
// Execute query to compute total
|
||||
TypedQuery<Long> projection = repositoryQuery.createCountQuery(values);
|
||||
|
||||
List<Long> totals = projection.getResultList();
|
||||
Long total = totals.size() == 1 ? totals.get(0) : totals.size();
|
||||
|
||||
@@ -160,4 +161,4 @@ public abstract class JpaQueryExecution {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.regex.Pattern;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.From;
|
||||
@@ -270,6 +271,26 @@ public abstract class QueryUtils {
|
||||
return orders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a count query and transparently sums up all values returned.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Long executeCountQuery(TypedQuery<Long> query) {
|
||||
|
||||
Assert.notNull(query);
|
||||
|
||||
List<Long> totals = query.getResultList();
|
||||
Long total = 0L;
|
||||
|
||||
for (Long element : totals) {
|
||||
total += element == null ? 0 : element;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a criteria API {@link javax.persistence.criteria.Order} from the given {@link Order}.
|
||||
*
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.query.QueryUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -402,7 +403,7 @@ public class SimpleJpaRepository<T, ID extends Serializable> implements JpaRepos
|
||||
query.setFirstResult(pageable.getOffset());
|
||||
query.setMaxResults(pageable.getPageSize());
|
||||
|
||||
Long total = getCountQuery(spec).getSingleResult();
|
||||
Long total = QueryUtils.executeCountQuery(getCountQuery(spec));
|
||||
List<T> content = total > pageable.getOffset() ? query.getResultList() : Collections.<T> emptyList();
|
||||
|
||||
return new PageImpl<T>(content, pageable, total);
|
||||
|
||||
Reference in New Issue
Block a user