committed by
Christoph Strobl
parent
e1b76122ae
commit
826147e7cb
@@ -21,8 +21,6 @@ import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -77,9 +75,7 @@ class JpaKeysetScrollQueryCreator extends JpaQueryCreator {
|
||||
|
||||
Sort sortToUse = KeysetScrollSpecification.createSort(scrollPosition, sort, entityInformation);
|
||||
|
||||
Set<String> selection = new LinkedHashSet<>(returnedType.getInputProperties());
|
||||
sortToUse.forEach(it -> selection.add(it.getProperty()));
|
||||
|
||||
return selection;
|
||||
return KeysetScrollDelegate.getProjectionInputProperties(entityInformation, returnedType.getInputProperties(),
|
||||
sortToUse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package org.springframework.data.jpa.repository.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -24,6 +26,7 @@ import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.ScrollPosition.Direction;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -47,6 +50,25 @@ public class KeysetScrollDelegate {
|
||||
return direction == Direction.FORWARD ? FORWARD : REVERSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collection of property names required to construct a keyset selection query that include all keyset and
|
||||
* identifier properties required to resume keyset scrolling.
|
||||
*
|
||||
* @param entity the underlying entity.
|
||||
* @param projectionProperties projection property names.
|
||||
* @param sort sort properties.
|
||||
* @return a collection of property names required to construct a keyset selection query
|
||||
*/
|
||||
public static Collection<String> getProjectionInputProperties(JpaEntityInformation<?, ?> entity,
|
||||
Collection<String> projectionProperties, Sort sort) {
|
||||
|
||||
Collection<String> properties = new LinkedHashSet<>(projectionProperties);
|
||||
sort.forEach(it -> properties.add(it.getProperty()));
|
||||
properties.addAll(entity.getIdAttributeNames());
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <E, P> P createPredicate(KeysetScrollPosition keyset, Sort sort, QueryStrategy<E, P> strategy) {
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import jakarta.persistence.EntityManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
@@ -34,6 +33,7 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.jpa.repository.query.KeysetScrollDelegate;
|
||||
import org.springframework.data.jpa.repository.query.ScrollDelegate;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
|
||||
@@ -219,13 +219,11 @@ class FetchableFluentQueryByPredicate<S, R> extends FluentQuerySupport<S, R> imp
|
||||
|
||||
List<String> inputProperties = returnedType.getInputProperties();
|
||||
|
||||
if (returnedType.needsCustomConstruction() && !inputProperties.isEmpty()) {
|
||||
if (returnedType.needsCustomConstruction()) {
|
||||
|
||||
Collection<String> requiredSelection;
|
||||
if (scrollPosition instanceof KeysetScrollPosition && returnedType.getReturnedType().isInterface()) {
|
||||
requiredSelection = new LinkedHashSet<>(inputProperties);
|
||||
sort.forEach(it -> requiredSelection.add(it.getProperty()));
|
||||
entityInformation.getIdAttributeNames().forEach(requiredSelection::add);
|
||||
requiredSelection = KeysetScrollDelegate.getProjectionInputProperties(entityInformation, inputProperties, sort);
|
||||
} else {
|
||||
requiredSelection = inputProperties;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -58,6 +57,7 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.provider.PersistenceProvider;
|
||||
import org.springframework.data.jpa.repository.EntityGraph;
|
||||
import org.springframework.data.jpa.repository.query.EscapeCharacter;
|
||||
import org.springframework.data.jpa.repository.query.KeysetScrollDelegate;
|
||||
import org.springframework.data.jpa.repository.query.KeysetScrollSpecification;
|
||||
import org.springframework.data.jpa.repository.query.QueryUtils;
|
||||
import org.springframework.data.jpa.repository.support.FetchableFluentQueryBySpecification.SpecificationScrollDelegate;
|
||||
@@ -776,7 +776,7 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
|
||||
|
||||
List<String> inputProperties = returnedType.getInputProperties();
|
||||
|
||||
if (returnedType.needsCustomConstruction() && !inputProperties.isEmpty()) {
|
||||
if (returnedType.needsCustomConstruction()) {
|
||||
query = (CriteriaQuery) (returnedType.getReturnedType().isInterface() ? builder.createTupleQuery()
|
||||
: builder.createQuery(returnedType.getReturnedType()));
|
||||
} else {
|
||||
@@ -785,14 +785,12 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
|
||||
|
||||
Root<S> root = applySpecificationToCriteria(spec, domainClass, query);
|
||||
|
||||
if (returnedType.needsCustomConstruction() && !inputProperties.isEmpty()) {
|
||||
if (returnedType.needsCustomConstruction()) {
|
||||
|
||||
Collection<String> requiredSelection;
|
||||
|
||||
if (scrollPosition instanceof KeysetScrollPosition && returnedType.getReturnedType().isInterface()) {
|
||||
requiredSelection = new LinkedHashSet<>(inputProperties);
|
||||
sort.stream().map(Sort.Order::getProperty).forEach(requiredSelection::add);
|
||||
entityInformation.getIdAttributeNames().forEach(requiredSelection::add);
|
||||
requiredSelection = KeysetScrollDelegate.getProjectionInputProperties(entityInformation, inputProperties, sort);
|
||||
} else {
|
||||
requiredSelection = inputProperties;
|
||||
}
|
||||
|
||||
@@ -2960,6 +2960,16 @@ class UserRepositoryTests {
|
||||
assertThat(users).hasSize(1);
|
||||
}
|
||||
|
||||
@Test // GH-2327
|
||||
void dynamicOpenProjectionReturningList() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
List<UserProjectionUsingSpEL> users = repository.findAsListByFirstnameLike("%O%", UserProjectionUsingSpEL.class);
|
||||
|
||||
assertThat(users).hasSize(1);
|
||||
}
|
||||
|
||||
@Test // DATAJPA-1179
|
||||
void duplicateSpelsWorkAsIntended() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user