Skip to content

Commit 0aa6d7d

Browse files
gregturnschauder
authored andcommitted
Apply query hints to count queries for page-based Specification.
Query hints are applied in many places, but not when doing a findAll(Specification, Pageable). Closes #2054. Original pull request #2528
1 parent 7245389 commit 0aa6d7d

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,13 @@ protected QueryHints getQueryHints() {
309309
return metadata == null ? NoHints.INSTANCE : DefaultQueryHints.of(entityInformation, metadata);
310310
}
311311

312+
/**
313+
* Returns {@link QueryHints} with the query hints on the current {@link CrudMethodMetadata} for count queries.
314+
*/
315+
protected QueryHints getQueryHintsForCount() {
316+
return metadata == null ? NoHints.INSTANCE : DefaultQueryHints.of(entityInformation, metadata).forCounts();
317+
}
318+
312319
@Deprecated
313320
@Override
314321
public T getOne(ID id) {
@@ -750,7 +757,7 @@ protected <S extends T> TypedQuery<Long> getCountQuery(@Nullable Specification<S
750757
// Remove all Orders the Specifications might have applied
751758
query.orderBy(Collections.emptyList());
752759

753-
return em.createQuery(query);
760+
return applyRepositoryMethodMetadataForCount(em.createQuery(query));
754761
}
755762

756763
/**
@@ -800,6 +807,21 @@ private void applyQueryHints(Query query) {
800807
getQueryHints().withFetchGraphs(em).forEach(query::setHint);
801808
}
802809

810+
private <S> TypedQuery<S> applyRepositoryMethodMetadataForCount(TypedQuery<S> query) {
811+
812+
if (metadata == null) {
813+
return query;
814+
}
815+
816+
applyQueryHintsForCount(query);
817+
818+
return query;
819+
}
820+
821+
private void applyQueryHintsForCount(Query query) {
822+
getQueryHintsForCount().forEach(query::setHint);
823+
}
824+
803825
/**
804826
* Executes a count query and transparently sums up all values returned.
805827
*

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/SimpleJpaRepositoryUnitTests.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@
1818
import static java.util.Collections.*;
1919
import static org.assertj.core.api.Assertions.*;
2020
import static org.mockito.Mockito.*;
21-
22-
import java.util.Arrays;
23-
import java.util.Optional;
21+
import static org.springframework.data.jpa.domain.Specification.*;
2422

2523
import jakarta.persistence.EntityGraph;
2624
import jakarta.persistence.EntityManager;
2725
import jakarta.persistence.TypedQuery;
2826
import jakarta.persistence.criteria.CriteriaBuilder;
2927
import jakarta.persistence.criteria.CriteriaQuery;
3028

29+
import java.util.Arrays;
30+
import java.util.Optional;
31+
3132
import org.junit.jupiter.api.BeforeEach;
3233
import org.junit.jupiter.api.Test;
3334
import org.junit.jupiter.api.extension.ExtendWith;
@@ -192,4 +193,14 @@ void doNothingWhenNonExistentInstanceGetsDeleted() {
192193
verify(em, never()).remove(newUser);
193194
verify(em, never()).merge(newUser);
194195
}
196+
197+
@Test // GH-2054
198+
void applyQueryHintsToCountQueriesForSpecificationPageables() {
199+
200+
when(query.getResultList()).thenReturn(Arrays.asList(new User(), new User()));
201+
202+
repo.findAll(where(null), PageRequest.of(2, 1));
203+
204+
verify(metadata).getQueryHintsForCount();
205+
}
195206
}

0 commit comments

Comments
 (0)