From 4d42a8c583a27d3d673fa9f6f4d33a64934adc18 Mon Sep 17 00:00:00 2001 From: Joshua Chen <27291761@qq.com> Date: Sat, 28 Dec 2024 15:02:46 +0800 Subject: [PATCH 1/4] Support custom countSpec in SimpleJpaRepository.findAll --- .../repository/JpaSpecificationExecutor.java | 21 +++++-- .../support/SimpleJpaRepository.java | 55 ++++++------------- 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java index 0d38cc580d..47a640e093 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java @@ -18,11 +18,6 @@ import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Root; - -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -30,6 +25,10 @@ import org.springframework.data.repository.query.FluentQuery; import org.springframework.lang.Nullable; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + /** * Interface to allow execution of {@link Specification}s based on the JPA criteria API. * @@ -70,6 +69,18 @@ public interface JpaSpecificationExecutor { */ Page findAll(@Nullable Specification spec, Pageable pageable); + /** + * Returns a {@link Page} of entities matching the given {@link Specification}. + * Supports counting the total number of entities matching the {@link Specification}. + *

+ * + * @param spec can be {@literal null}, if no {@link Specification} is given all entities matching {@code } will be selected. + * @param countSpec can be {@literal null},if no {@link Specification} is given all entities matching {@code } will be counted. + * @param pageable must not be {@literal null}. + * @return never {@literal null}. + */ + Page findAll(@Nullable Specification spec, @Nullable Specification countSpec, Pageable pageable); + /** * Returns all entities matching the given {@link Specification} and {@link Sort}. *

diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index bb784e2115..19c051db60 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -15,43 +15,9 @@ */ package org.springframework.data.jpa.repository.support; -import static org.springframework.data.jpa.repository.query.QueryUtils.*; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.LockModeType; -import jakarta.persistence.NoResultException; -import jakarta.persistence.Parameter; -import jakarta.persistence.Query; -import jakarta.persistence.TypedQuery; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaDelete; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.ParameterExpression; -import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import jakarta.persistence.criteria.Selection; - -import java.io.Serial; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; - -import org.springframework.data.domain.Example; -import org.springframework.data.domain.KeysetScrollPosition; -import org.springframework.data.domain.OffsetScrollPosition; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Sort; +import jakarta.persistence.*; +import jakarta.persistence.criteria.*; +import org.springframework.data.domain.*; import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.provider.PersistenceProvider; @@ -77,6 +43,14 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import java.io.Serial; +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +import static org.springframework.data.jpa.repository.query.QueryUtils.*; + /** * Default implementation of the {@link org.springframework.data.repository.CrudRepository} interface. This will offer * you a more sophisticated interface than the plain {@link EntityManager} . @@ -455,10 +429,15 @@ public List findAll(Specification spec) { @Override public Page findAll(@Nullable Specification spec, Pageable pageable) { + return findAll(spec, spec, pageable); + } + + @Override + public Page findAll(@Nullable Specification spec, @Nullable Specification countSpec, Pageable pageable) { TypedQuery query = getQuery(spec, pageable); return pageable.isUnpaged() ? new PageImpl<>(query.getResultList()) - : readPage(query, getDomainClass(), pageable, spec); + : readPage(query, getDomainClass(), pageable, countSpec); } @Override From 2f53bfdf7f67260f9441dc9aa28545ece02cb445 Mon Sep 17 00:00:00 2001 From: Joshua Chen <27291761@qq.com> Date: Sat, 28 Dec 2024 15:19:04 +0800 Subject: [PATCH 2/4] add myself as author --- .../repository/JpaSpecificationExecutor.java | 1 + .../support/SimpleJpaRepository.java | 34 ++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java index 47a640e093..be74ad212b 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java @@ -36,6 +36,7 @@ * @author Christoph Strobl * @author Diego Krupitza * @author Mark Paluch + * @author Joshua Chen */ public interface JpaSpecificationExecutor { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 19c051db60..6c22a1b63c 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -15,9 +15,28 @@ */ package org.springframework.data.jpa.repository.support; -import jakarta.persistence.*; -import jakarta.persistence.criteria.*; -import org.springframework.data.domain.*; +import jakarta.persistence.EntityManager; +import jakarta.persistence.LockModeType; +import jakarta.persistence.NoResultException; +import jakarta.persistence.Parameter; +import jakarta.persistence.Query; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.ParameterExpression; +import jakarta.persistence.criteria.Path; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.Selection; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.KeysetScrollPosition; +import org.springframework.data.domain.OffsetScrollPosition; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.ScrollPosition; +import org.springframework.data.domain.Sort; import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.provider.PersistenceProvider; @@ -44,7 +63,13 @@ import org.springframework.util.Assert; import java.io.Serial; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; @@ -73,6 +98,7 @@ * @author Ernst-Jan van der Laan * @author Diego Krupitza * @author Seol-JY + * @author Joshua Chen */ @Repository @Transactional(readOnly = true) From 331940bbcbbd31fd7e3bfa3cc36802d262b1b075 Mon Sep 17 00:00:00 2001 From: Joshua Chen <27291761@qq.com> Date: Sat, 28 Dec 2024 15:41:33 +0800 Subject: [PATCH 3/4] Fix incorrect import order --- .../repository/JpaSpecificationExecutor.java | 9 +++--- .../support/SimpleJpaRepository.java | 29 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java index be74ad212b..ea97306670 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java @@ -18,6 +18,11 @@ import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Root; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -25,10 +30,6 @@ import org.springframework.data.repository.query.FluentQuery; import org.springframework.lang.Nullable; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - /** * Interface to allow execution of {@link Specification}s based on the JPA criteria API. * diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 6c22a1b63c..b31c60db58 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -15,6 +15,8 @@ */ package org.springframework.data.jpa.repository.support; +import static org.springframework.data.jpa.repository.query.QueryUtils.*; + import jakarta.persistence.EntityManager; import jakarta.persistence.LockModeType; import jakarta.persistence.NoResultException; @@ -29,6 +31,19 @@ import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Selection; + +import java.io.Serial; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + import org.springframework.data.domain.Example; import org.springframework.data.domain.KeysetScrollPosition; import org.springframework.data.domain.OffsetScrollPosition; @@ -62,20 +77,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; -import java.io.Serial; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; - -import static org.springframework.data.jpa.repository.query.QueryUtils.*; - /** * Default implementation of the {@link org.springframework.data.repository.CrudRepository} interface. This will offer * you a more sophisticated interface than the plain {@link EntityManager} . From 1f568557f645b5715be108db919f786f46722629 Mon Sep 17 00:00:00 2001 From: Joshua Chen <27291761@qq.com> Date: Sat, 28 Dec 2024 23:48:25 +0800 Subject: [PATCH 4/4] Fix incorrect code formats --- .../data/jpa/repository/JpaSpecificationExecutor.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java index ea97306670..5954833b3a 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java @@ -73,12 +73,15 @@ public interface JpaSpecificationExecutor { /** * Returns a {@link Page} of entities matching the given {@link Specification}. + *

* Supports counting the total number of entities matching the {@link Specification}. *

* - * @param spec can be {@literal null}, if no {@link Specification} is given all entities matching {@code } will be selected. - * @param countSpec can be {@literal null},if no {@link Specification} is given all entities matching {@code } will be counted. - * @param pageable must not be {@literal null}. + * @param spec can be {@literal null}, if no {@link Specification} is given all entities matching {@code } will be + * selected. + * @param countSpec can be {@literal null},if no {@link Specification} is given all entities matching {@code } will + * be counted. + * @param pageable must not be {@literal null}. * @return never {@literal null}. */ Page findAll(@Nullable Specification spec, @Nullable Specification countSpec, Pageable pageable);