From aee865f2d2843fd28dd75bae908344b04968889b Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 27 May 2016 16:43:00 +0200 Subject: [PATCH] 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. --- .../support/SimpleJpaRepository.java | 4 ++++ .../jpa/domain/sample/UserSpecifications.java | 24 +++++++++++++++++-- .../jpa/repository/UserRepositoryTests.java | 15 ++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 5376c13c1..4349bd3b1 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -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; @@ -560,6 +561,9 @@ public class SimpleJpaRepository implements JpaRepos query.select(builder.count(root)); } + // Remove all Orders the Specifications might have applied + query.orderBy(Collections. emptyList()); + return em.createQuery(query); } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java b/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java index 8308d08e7..7af93d8c2 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java @@ -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 userHasLastnameLikeWithSort(final String expression) { + + return new Specification() { + + public Predicate toPredicate(Root 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 Specification simplePropertySpec(final String property, final Object value) { return new Specification() { @@ -78,4 +98,4 @@ public class UserSpecifications { } }; } -} \ No newline at end of file +} diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index e4f644203..ef48e0eca 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -1903,6 +1903,21 @@ public class UserRepositoryTests { } assertThat(users, hasSize(2)); + } + + /** + * @see DATAJPA-905 + */ + @Test + public void excutesPagedSpecificationSettingAnOrder() { + + flushTestUsers(); + + Page 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 executeSpecWithSort(Sort sort) {