Skip to content

Commit 1a532b8

Browse files
committed
Polishing.
Refactor code duplications. See #2327
1 parent de5fb64 commit 1a532b8

File tree

5 files changed

+41
-17
lines changed

5 files changed

+41
-17
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaKeysetScrollQueryCreator.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import jakarta.persistence.criteria.Root;
2222

2323
import java.util.Collection;
24-
import java.util.LinkedHashSet;
25-
import java.util.Set;
2624

2725
import org.springframework.data.domain.KeysetScrollPosition;
2826
import org.springframework.data.domain.Sort;
@@ -77,9 +75,7 @@ Collection<String> getRequiredSelection(Sort sort, ReturnedType returnedType) {
7775

7876
Sort sortToUse = KeysetScrollSpecification.createSort(scrollPosition, sort, entityInformation);
7977

80-
Set<String> selection = new LinkedHashSet<>(returnedType.getInputProperties());
81-
sortToUse.forEach(it -> selection.add(it.getProperty()));
82-
83-
return selection;
78+
return KeysetScrollDelegate.getProjectionInputProperties(entityInformation, returnedType.getInputProperties(),
79+
sortToUse);
8480
}
8581
}

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java

+22
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616
package org.springframework.data.jpa.repository.query;
1717

1818
import java.util.ArrayList;
19+
import java.util.Collection;
1920
import java.util.Collections;
21+
import java.util.LinkedHashSet;
2022
import java.util.List;
2123
import java.util.Map;
2224

2325
import org.springframework.data.domain.KeysetScrollPosition;
2426
import org.springframework.data.domain.ScrollPosition.Direction;
2527
import org.springframework.data.domain.Sort;
2628
import org.springframework.data.domain.Sort.Order;
29+
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
2730
import org.springframework.lang.Nullable;
2831

2932
/**
@@ -47,6 +50,25 @@ public static KeysetScrollDelegate of(Direction direction) {
4750
return direction == Direction.FORWARD ? FORWARD : REVERSE;
4851
}
4952

53+
/**
54+
* Return a collection of property names required to construct a keyset selection query that include all keyset and
55+
* identifier properties required to resume keyset scrolling.
56+
*
57+
* @param entity the underlying entity.
58+
* @param projectionProperties projection property names.
59+
* @param sort sort properties.
60+
* @return a collection of property names required to construct a keyset selection query
61+
*/
62+
public static Collection<String> getProjectionInputProperties(JpaEntityInformation<?, ?> entity,
63+
Collection<String> projectionProperties, Sort sort) {
64+
65+
Collection<String> properties = new LinkedHashSet<>(projectionProperties);
66+
sort.forEach(it -> properties.add(it.getProperty()));
67+
properties.addAll(entity.getIdAttributeNames());
68+
69+
return properties;
70+
}
71+
5072
@Nullable
5173
public <E, P> P createPredicate(KeysetScrollPosition keyset, Sort sort, QueryStrategy<E, P> strategy) {
5274

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.ArrayList;
2121
import java.util.Collection;
2222
import java.util.Collections;
23-
import java.util.LinkedHashSet;
2423
import java.util.List;
2524
import java.util.function.BiFunction;
2625
import java.util.function.Function;
@@ -34,6 +33,7 @@
3433
import org.springframework.data.domain.ScrollPosition;
3534
import org.springframework.data.domain.Sort;
3635
import org.springframework.data.domain.Window;
36+
import org.springframework.data.jpa.repository.query.KeysetScrollDelegate;
3737
import org.springframework.data.jpa.repository.query.ScrollDelegate;
3838
import org.springframework.data.projection.ProjectionFactory;
3939
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
@@ -219,13 +219,11 @@ private void applyQuerySettings(ReturnedType returnedType, int limit, AbstractJP
219219

220220
List<String> inputProperties = returnedType.getInputProperties();
221221

222-
if (returnedType.needsCustomConstruction() && !inputProperties.isEmpty()) {
222+
if (returnedType.needsCustomConstruction()) {
223223

224224
Collection<String> requiredSelection;
225225
if (scrollPosition instanceof KeysetScrollPosition && returnedType.getReturnedType().isInterface()) {
226-
requiredSelection = new LinkedHashSet<>(inputProperties);
227-
sort.forEach(it -> requiredSelection.add(it.getProperty()));
228-
entityInformation.getIdAttributeNames().forEach(requiredSelection::add);
226+
requiredSelection = KeysetScrollDelegate.getProjectionInputProperties(entityInformation, inputProperties, sort);
229227
} else {
230228
requiredSelection = inputProperties;
231229
}

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

+4-6
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import java.util.Collection;
3838
import java.util.Collections;
3939
import java.util.HashMap;
40-
import java.util.LinkedHashSet;
4140
import java.util.List;
4241
import java.util.Map;
4342
import java.util.Optional;
@@ -58,6 +57,7 @@
5857
import org.springframework.data.jpa.provider.PersistenceProvider;
5958
import org.springframework.data.jpa.repository.EntityGraph;
6059
import org.springframework.data.jpa.repository.query.EscapeCharacter;
60+
import org.springframework.data.jpa.repository.query.KeysetScrollDelegate;
6161
import org.springframework.data.jpa.repository.query.KeysetScrollSpecification;
6262
import org.springframework.data.jpa.repository.query.QueryUtils;
6363
import org.springframework.data.jpa.repository.support.FetchableFluentQueryBySpecification.SpecificationScrollDelegate;
@@ -772,7 +772,7 @@ private <S extends T> TypedQuery<S> getQuery(ReturnedType returnedType, @Nullabl
772772

773773
List<String> inputProperties = returnedType.getInputProperties();
774774

775-
if (returnedType.needsCustomConstruction() && !inputProperties.isEmpty()) {
775+
if (returnedType.needsCustomConstruction()) {
776776
query = (CriteriaQuery) (returnedType.getReturnedType().isInterface() ? builder.createTupleQuery()
777777
: builder.createQuery(returnedType.getReturnedType()));
778778
} else {
@@ -781,14 +781,12 @@ private <S extends T> TypedQuery<S> getQuery(ReturnedType returnedType, @Nullabl
781781

782782
Root<S> root = applySpecificationToCriteria(spec, domainClass, query);
783783

784-
if (returnedType.needsCustomConstruction() && !inputProperties.isEmpty()) {
784+
if (returnedType.needsCustomConstruction()) {
785785

786786
Collection<String> requiredSelection;
787787

788788
if (scrollPosition instanceof KeysetScrollPosition && returnedType.getReturnedType().isInterface()) {
789-
requiredSelection = new LinkedHashSet<>(inputProperties);
790-
sort.stream().map(Sort.Order::getProperty).forEach(requiredSelection::add);
791-
entityInformation.getIdAttributeNames().forEach(requiredSelection::add);
789+
requiredSelection = KeysetScrollDelegate.getProjectionInputProperties(entityInformation, inputProperties, sort);
792790
} else {
793791
requiredSelection = inputProperties;
794792
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -2958,6 +2958,16 @@ void dynamicProjectionReturningList() {
29582958
assertThat(users).hasSize(1);
29592959
}
29602960

2961+
@Test // GH-2327
2962+
void dynamicOpenProjectionReturningList() {
2963+
2964+
flushTestUsers();
2965+
2966+
List<UserProjectionUsingSpEL> users = repository.findAsListByFirstnameLike("%O%", UserProjectionUsingSpEL.class);
2967+
2968+
assertThat(users).hasSize(1);
2969+
}
2970+
29612971
@Test // DATAJPA-1179
29622972
void duplicateSpelsWorkAsIntended() {
29632973

0 commit comments

Comments
 (0)