Skip to content

Commit f91bd3d

Browse files
radovanradicdstepanov
authored andcommitted
Apply count distinct to the criteria query when specified in the paging count query (#2766)
(cherry picked from commit 47fc3cd)
1 parent a7d77c0 commit f91bd3d

File tree

7 files changed

+46
-8
lines changed

7 files changed

+46
-8
lines changed

data-hibernate-jpa/src/test/groovy/io/micronaut/data/hibernate/JpaSpecificationCrudRepositorySpec.groovy

+4
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ class JpaSpecificationCrudRepositorySpec extends Specification {
102102
results.size() == 4
103103
results.every({ it instanceof Person})
104104

105+
def pageReq = Pageable.from(0, 2, Sort.of(Sort.Order.asc("age")))
106+
def page = crudRepository.findAll(JpaSpecificationCrudRepository.Specifications.ageGreaterThanThirty(true), pageReq)
107+
page.totalSize <= 4
108+
105109
def sorted = crudRepository.findAll(JpaSpecificationCrudRepository.Specifications.ageGreaterThanThirty(), Sort.of(Sort.Order.asc("age")))
106110

107111
sorted.first().name == "James"

data-hibernate-jpa/src/test/java/io/micronaut/data/hibernate/JpaSpecificationCrudRepository.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,18 @@ public interface JpaSpecificationCrudRepository extends CrudRepository<Person, L
7272

7373
class Specifications {
7474
public static Specification<Person> ageGreaterThanThirty() {
75-
return (root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(
75+
return ageGreaterThanThirty(false);
76+
}
77+
78+
public static Specification<Person> ageGreaterThanThirty(boolean countDistinct) {
79+
return (root, query, criteriaBuilder) -> {
80+
if (countDistinct && query.getResultType() == Long.class) {
81+
query.distinct(true);
82+
}
83+
return criteriaBuilder.greaterThan(
7684
root.get("age"), 30
77-
);
85+
);
86+
};
7887
}
7988

8089
public static Specification<Person> nameEquals(String name) {

data-hibernate-reactive/src/main/java/io/micronaut/data/hibernate/reactive/repository/jpa/intercept/ReactiveFindPageSpecificationInterceptor.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ protected Publisher<?> interceptPublisher(RepositoryMethodKey methodKey, MethodI
9797
if (countPredicate != null) {
9898
countQuery.where(countPredicate);
9999
}
100-
countQuery.select(criteriaBuilder.count(countRoot));
100+
if (countQuery.isDistinct()) {
101+
countQuery.select(criteriaBuilder.countDistinct(countRoot));
102+
} else {
103+
countQuery.select(criteriaBuilder.count(countRoot));
104+
}
101105
return Mono.fromCompletionStage(() -> session.createQuery(countQuery).getSingleResult())
102106
.map(total -> Page.of(results, pageable, total));
103107
});

data-jpa/src/main/java/io/micronaut/data/jpa/repository/intercept/FindPageSpecificationInterceptor.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ public Page intercept(RepositoryMethodKey methodKey, MethodInvocationContext<Obj
107107
if (countPredicate != null) {
108108
countQuery.where(countPredicate);
109109
}
110-
countQuery.select(criteriaBuilder.count(countRoot));
110+
if (countQuery.isDistinct()) {
111+
countQuery.select(criteriaBuilder.countDistinct(countRoot));
112+
} else {
113+
countQuery.select(criteriaBuilder.count(countRoot));
114+
}
111115
Long singleResult = entityManager.createQuery(countQuery).getSingleResult();
112116

113117
return Page.of(

data-spring-jpa/src/main/java/io/micronaut/data/spring/jpa/intercept/FindPageSpecificationInterceptor.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,13 @@ public Object intercept(RepositoryMethodKey methodKey, MethodInvocationContext<O
101101
final List<Object> results = typedQuery.getResultList();
102102
final CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
103103
final Root<?> countRoot = countQuery.from(getRequiredRootEntity(context));
104-
final Predicate countPredicate = specification.toPredicate(countRoot, query, criteriaBuilder);
104+
final Predicate countPredicate = specification.toPredicate(countRoot, countQuery, criteriaBuilder);
105105
countQuery.where(countPredicate);
106-
countQuery.select(criteriaBuilder.count(countRoot));
106+
if (countQuery.isDistinct()) {
107+
countQuery.select(criteriaBuilder.countDistinct(countRoot));
108+
} else {
109+
countQuery.select(criteriaBuilder.count(countRoot));
110+
}
107111

108112
return new PageImpl<>(
109113
results,

data-spring-jpa/src/test/groovy/io/micronaut/data/spring/hibernate/SpringCrudRepositoryJpaSpec.groovy

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ class SpringCrudRepositoryJpaSpec extends Specification implements H2Properties
8181
results.size() == 4
8282
results.every({ it instanceof Person})
8383

84+
def pageReq = PageRequest.of(0, 2, Sort.by("age"))
85+
def page = crudRepository.findAll(SpringCrudRepository.Specifications.ageGreaterThanThirty(true), pageReq)
86+
page.totalElements <= 4
87+
8488
def sorted = crudRepository.findAll(SpringCrudRepository.Specifications.ageGreaterThanThirty(), Sort.by("age"))
8589

8690
sorted.first().name == "James"

data-spring-jpa/src/test/java/io/micronaut/data/spring/hibernate/spring/SpringCrudRepository.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,18 @@ public interface SpringCrudRepository extends CrudRepository<Person, Long>, JpaS
7373

7474
class Specifications {
7575
public static Specification<Person> ageGreaterThanThirty() {
76-
return (root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(
76+
return ageGreaterThanThirty(false);
77+
}
78+
79+
public static Specification<Person> ageGreaterThanThirty(boolean countDistinct) {
80+
return (root, query, criteriaBuilder) -> {
81+
if (countDistinct && query.getResultType() == Long.class) {
82+
query.distinct(true);
83+
}
84+
return criteriaBuilder.greaterThan(
7785
root.get("age"), 30
78-
);
86+
);
87+
};
7988
}
8089

8190
public static Specification<Person> nameEquals(String name) {

0 commit comments

Comments
 (0)