DATAJPA-551 - Add support for limiting the query result in the query derivation mechanism.
We now support to restrict the results of a query method via the "Top" or "First" keyword within the method name. We adjust the firstResult offset of the query in case we detect a tighter bound on the result size limit form the derived query method that is smaller than the page size of the given Pageable. Added test cases for Paged and Sliced query executions. Original pull request: #96.
This commit is contained in:
committed by
Oliver Gierke
parent
09d32cb3f5
commit
43d035fe54
@@ -128,7 +128,37 @@ public class PartTreeJpaQuery extends AbstractJpaQuery {
|
||||
}
|
||||
|
||||
TypedQuery<?> jpaQuery = createQuery(criteriaQuery);
|
||||
return invokeBinding(getBinder(values, expressions), jpaQuery);
|
||||
|
||||
return restrictMaxResultsIfNecessary(invokeBinding(getBinder(values, expressions), jpaQuery));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricts the max results of the given {@link Query} if the current {@code tree} marks this {@code query} as
|
||||
* limited.
|
||||
*
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
private Query restrictMaxResultsIfNecessary(Query query) {
|
||||
|
||||
if (tree.isLimiting()) {
|
||||
|
||||
if (query.getMaxResults() != Integer.MAX_VALUE) {
|
||||
/*
|
||||
* In order to return the correct results, we have to adjust the first result offset to be returned if:
|
||||
* - a Pageable parameter is present
|
||||
* - AND the requested page number > 0
|
||||
* - AND the requested page size was bigger than the derived result limitation via the First/Top keyword.
|
||||
*/
|
||||
if (query.getMaxResults() > tree.getMaxResults() && query.getFirstResult() > 0) {
|
||||
query.setFirstResult(query.getFirstResult() - (query.getMaxResults() - tree.getMaxResults()));
|
||||
}
|
||||
}
|
||||
|
||||
query.setMaxResults(tree.getMaxResults());
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
@@ -1421,6 +1422,140 @@ public class UserRepositoryTests {
|
||||
assertThat(result.getContent().size(), is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void findOldestUser() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User oldest = thirdUser;
|
||||
|
||||
assertThat(repository.findFirstByOrderByAgeDesc(), is(oldest));
|
||||
assertThat(repository.findFirst1ByOrderByAgeDesc(), is(oldest));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void findYoungestUser() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User youngest = firstUser;
|
||||
|
||||
assertThat(repository.findTopByOrderByAgeAsc(), is(youngest));
|
||||
assertThat(repository.findTop1ByOrderByAgeAsc(), is(youngest));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void find2OldestUsers() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User oldest1 = thirdUser;
|
||||
User oldest2 = secondUser;
|
||||
|
||||
assertThat(repository.findFirst2ByOrderByAgeDesc(), hasItems(oldest1, oldest2));
|
||||
assertThat(repository.findTop2ByOrderByAgeDesc(), hasItems(oldest1, oldest2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void find2YoungestUsers() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User youngest1 = firstUser;
|
||||
User youngest2 = fourthUser;
|
||||
|
||||
assertThat(repository.findFirst2UsersBy(new Sort(ASC, "age")), hasItems(youngest1, youngest2));
|
||||
assertThat(repository.findTop2UsersBy(new Sort(ASC, "age")), hasItems(youngest1, youngest2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void find3YoungestUsersPageableWithPageSize2() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User youngest1 = firstUser;
|
||||
User youngest2 = fourthUser;
|
||||
User youngest3 = secondUser;
|
||||
|
||||
Page<User> firstPage = repository.findFirst3UsersBy(new PageRequest(0, 2, ASC, "age"));
|
||||
assertThat(firstPage.getContent(), hasItems(youngest1, youngest2));
|
||||
|
||||
Page<User> secondPage = repository.findFirst3UsersBy(new PageRequest(1, 2, ASC, "age"));
|
||||
assertThat(secondPage.getContent(), hasItems(youngest3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void find2YoungestUsersPageableWithPageSize3() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User youngest1 = firstUser;
|
||||
User youngest2 = fourthUser;
|
||||
User youngest3 = secondUser;
|
||||
|
||||
Page<User> firstPage = repository.findFirst2UsersBy(new PageRequest(0, 3, ASC, "age"));
|
||||
assertThat(firstPage.getContent(), hasItems(youngest1, youngest2));
|
||||
|
||||
Page<User> secondPage = repository.findFirst2UsersBy(new PageRequest(1, 3, ASC, "age"));
|
||||
assertThat(secondPage.getContent(), hasItems(youngest3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void find3YoungestUsersPageableWithPageSize2Sliced() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User youngest1 = firstUser;
|
||||
User youngest2 = fourthUser;
|
||||
User youngest3 = secondUser;
|
||||
|
||||
Slice<User> firstPage = repository.findTop3UsersBy(new PageRequest(0, 2, ASC, "age"));
|
||||
assertThat(firstPage.getContent(), hasItems(youngest1, youngest2));
|
||||
|
||||
Slice<User> secondPage = repository.findTop3UsersBy(new PageRequest(1, 2, ASC, "age"));
|
||||
assertThat(secondPage.getContent(), hasItems(youngest3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
@Test
|
||||
public void find2YoungestUsersPageableWithPageSize3Sliced() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
User youngest1 = firstUser;
|
||||
User youngest2 = fourthUser;
|
||||
User youngest3 = secondUser;
|
||||
|
||||
Slice<User> firstPage = repository.findTop2UsersBy(new PageRequest(0, 3, ASC, "age"));
|
||||
assertThat(firstPage.getContent(), hasItems(youngest1, youngest2));
|
||||
|
||||
Slice<User> secondPage = repository.findTop2UsersBy(new PageRequest(1, 3, ASC, "age"));
|
||||
assertThat(secondPage.getContent(), hasItems(youngest3));
|
||||
}
|
||||
|
||||
private Page<User> executeSpecWithSort(Sort sort) {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
@@ -380,4 +380,69 @@ public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecifi
|
||||
*/
|
||||
@Query(name = "User.findBySpringDataNamedQuery", countProjection = "u.firstname")
|
||||
Page<User> findByNamedQueryAndCountProjection(String firstname, Pageable page);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
User findFirstByOrderByAgeDesc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
User findFirst1ByOrderByAgeDesc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
User findTopByOrderByAgeDesc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
User findTopByOrderByAgeAsc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
User findTop1ByOrderByAgeAsc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
List<User> findTop2ByOrderByAgeDesc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
List<User> findFirst2ByOrderByAgeDesc();
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
List<User> findFirst2UsersBy(Sort sort);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
List<User> findTop2UsersBy(Sort sort);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
Page<User> findFirst3UsersBy(Pageable page);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
Page<User> findFirst2UsersBy(Pageable page);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
Slice<User> findTop3UsersBy(Pageable page);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-551
|
||||
*/
|
||||
Slice<User> findTop2UsersBy(Pageable page);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user