DATAJPA-905 - Count queries for Specifications don't use orders anymore.

Count queries that are executed in the context of paginated queries using Specifications now get their order specifications removed as they get rejected by some databases.
This commit is contained in:
Oliver Gierke
2016-05-27 16:43:00 +02:00
parent 6a51f4cc45
commit d06ec589db
3 changed files with 41 additions and 14 deletions

View File

@@ -33,6 +33,7 @@ import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
@@ -678,21 +679,12 @@ public class SimpleJpaRepository<T, ID extends Serializable>
query.select(builder.count(root));
}
// Remove all Orders the Specifications might have applied
query.orderBy(Collections.<Order> emptyList());
return em.createQuery(query);
}
/**
* Applies the given {@link Specification} to the given {@link CriteriaQuery}.
*
* @param spec can be {@literal null}.
* @param query must not be {@literal null}.
* @return
*/
private <S> Root<T> applySpecificationToCriteria(Specification<T> spec, CriteriaQuery<S> query) {
return applySpecificationToCriteria(spec, getDomainClass(), query);
}
/**
* Applies the given {@link Specification} to the given {@link CriteriaQuery}.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 the original author or authors.
* Copyright 2008-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,6 +68,26 @@ public class UserSpecifications {
};
}
/**
* A {@link Specification} to do a like-match on a {@link User}'s lastname but also adding a sort order on the
* firstname.
*
* @param firstname
* @return
*/
public static Specification<User> userHasLastnameLikeWithSort(final String expression) {
return new Specification<User>() {
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
query.orderBy(cb.asc(root.get("firstname")));
return cb.like(root.get("lastname").as(String.class), String.format("%%%s%%", expression));
}
};
}
private static <T> Specification<T> simplePropertySpec(final String property, final Object value) {
return new Specification<T>() {
@@ -78,4 +98,4 @@ public class UserSpecifications {
}
};
}
}
}

View File

@@ -2382,6 +2382,21 @@ public class UserRepositoryTests {
assertThat(exists, is(true));
}
/**
* @see DATAJPA-905
*/
@Test
public void excutesPagedSpecificationSettingAnOrder() {
flushTestUsers();
Page<User> result = repository.findAll(where(userHasLastnameLikeWithSort("e")), new PageRequest(0, 1));
assertThat(result.getTotalElements(), is(2L));
assertThat(result.getNumberOfElements(), is(1));
assertThat(result.getContent().get(0), is(thirdUser));
}
private Page<User> executeSpecWithSort(Sort sort) {
flushTestUsers();