Skip to content

Introduce QueryEnhancerSelector to configure which QueryEnhancerFactory to use #3527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-2989-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data JPA Parent</name>
Expand Down
4 changes: 2 additions & 2 deletions spring-data-envers/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-envers</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-2989-SNAPSHOT</version>

<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-2989-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-jpa-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-2989-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
4 changes: 2 additions & 2 deletions spring-data-jpa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-2989-SNAPSHOT</version>

<name>Spring Data JPA</name>
<description>Spring Data module for JPA repositories.</description>
Expand All @@ -16,7 +16,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-GH-2989-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.openjdk.jmh.annotations.Warmup;

import org.springframework.data.domain.Sort;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.query.ReturnedType;

/**
* @author Mark Paluch
Expand All @@ -44,6 +46,7 @@ public static class BenchmarkParameters {
DeclaredQuery query;
Sort sort = Sort.by("foo");
QueryEnhancer enhancer;
QueryEnhancer.QueryRewriteInformation rewriteInformation;

@Setup(Level.Iteration)
public void doSetup() {
Expand All @@ -55,14 +58,16 @@ OR TREAT(p AS SmallProject).name LIKE 'Persist%'
OR p.description LIKE "cost overrun"
""";

query = DeclaredQuery.of(s, false);
enhancer = QueryEnhancerFactory.forQuery(query);
query = DeclaredQuery.jpqlQuery(s);
enhancer = QueryEnhancerFactory.forQuery(query).create(query);
rewriteInformation = new DefaultQueryRewriteInformation(sort,
ReturnedType.of(Object.class, Object.class, new SpelAwareProxyProjectionFactory()));
}
}

@Benchmark
public Object measure(BenchmarkParameters parameters) {
return parameters.enhancer.applySorting(parameters.sort);
return parameters.enhancer.rewrite(parameters.rewriteInformation);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.openjdk.jmh.annotations.Warmup;

import org.springframework.data.domain.Sort;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.query.ReturnedType;

/**
* @author Mark Paluch
Expand All @@ -46,6 +48,7 @@ public static class BenchmarkParameters {
JSqlParserQueryEnhancer enhancer;
Sort sort = Sort.by("foo");
private byte[] serialized;
private QueryEnhancer.QueryRewriteInformation rewriteInformation;

@Setup(Level.Iteration)
public void doSetup() throws IOException {
Expand All @@ -56,13 +59,15 @@ public void doSetup() throws IOException {
select SOME_COLUMN from SOME_OTHER_TABLE where REPORTING_DATE = :REPORTING_DATE
union select SOME_COLUMN from SOME_OTHER_OTHER_TABLE""";

enhancer = new JSqlParserQueryEnhancer(DeclaredQuery.of(s, true));
enhancer = new JSqlParserQueryEnhancer(DeclaredQuery.nativeQuery(s));
rewriteInformation = new DefaultQueryRewriteInformation(sort,
ReturnedType.of(Object.class, Object.class, new SpelAwareProxyProjectionFactory()));
}
}

@Benchmark
public Object applySortWithParsing(BenchmarkParameters p) {
return p.enhancer.applySorting(p.sort);
return p.enhancer.rewrite(p.rewriteInformation);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,17 @@
*/
package org.springframework.data.jpa.repository;

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;

import java.util.Arrays;
import java.util.Collection;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.jspecify.annotations.Nullable;

import org.springframework.dao.InvalidDataAccessApiUsageException;

import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.DeleteSpecification;
import org.springframework.data.jpa.domain.PredicateSpecification;
Expand Down Expand Up @@ -115,7 +105,6 @@ default List<T> findAll(PredicateSpecification<T> spec) {
* Returns a {@link Page} of entities matching the given {@link Specification}.
* <p>
* Supports counting the total number of entities matching the {@link Specification}.
* <p>
*
* @param spec can be {@literal null}, if no {@link Specification} is given all entities matching {@code <T>} will be
* selected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,5 @@
* Name of the {@link jakarta.persistence.SqlResultSetMapping @SqlResultSetMapping(name)} to apply for this query.
*/
String sqlResultSetMapping() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,5 @@
* @since 3.0
*/
Class<? extends QueryRewriter> queryRewriter() default QueryRewriter.IdentityQueryRewriter.class;

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.jpa.repository.query.QueryEnhancerSelector;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.config.BootstrapMode;
import org.springframework.data.repository.config.DefaultRepositoryBaseClass;
Expand Down Expand Up @@ -83,46 +84,39 @@
* Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
* for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
* for {@code PersonRepositoryImpl}.
*
* @return
*/
String repositoryImplementationPostfix() default "Impl";

/**
* Configures the location of where to find the Spring Data named queries properties file. Will default to
* {@code META-INF/jpa-named-queries.properties}.
*
* @return
*/
String namedQueriesLocation() default "";

/**
* Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
* {@link Key#CREATE_IF_NOT_FOUND}.
*
* @return
*/
Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;

/**
* Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
* {@link JpaRepositoryFactoryBean}.
*
* @return
*/
Class<?> repositoryFactoryBeanClass() default JpaRepositoryFactoryBean.class;

/**
* Configure the repository base class to be used to create repository proxies for this particular configuration.
*
* @return
* @since 1.9
*/
Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class;

/**
* Configure a specific {@link BeanNameGenerator} to be used when creating the repository beans.
* @return the {@link BeanNameGenerator} to be used or the base {@link BeanNameGenerator} interface to indicate context default.
*
* @return the {@link BeanNameGenerator} to be used or the base {@link BeanNameGenerator} interface to indicate
* context default.
* @since 3.4
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Expand All @@ -132,22 +126,18 @@
/**
* Configures the name of the {@link EntityManagerFactory} bean definition to be used to create repositories
* discovered through this annotation. Defaults to {@code entityManagerFactory}.
*
* @return
*/
String entityManagerFactoryRef() default "entityManagerFactory";

/**
* Configures the name of the {@link PlatformTransactionManager} bean definition to be used to create repositories
* discovered through this annotation. Defaults to {@code transactionManager}.
*
* @return
*/
String transactionManagerRef() default "transactionManager";

/**
* Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
* repositories infrastructure.
* repository infrastructure.
*/
boolean considerNestedRepositories() default false;

Expand All @@ -169,7 +159,6 @@
* completed its bootstrap. {@link BootstrapMode#DEFERRED} is fundamentally the same as {@link BootstrapMode#LAZY},
* but triggers repository initialization when the application context finishes its bootstrap.
*
* @return
* @since 2.1
*/
BootstrapMode bootstrapMode() default BootstrapMode.DEFAULT;
Expand All @@ -181,4 +170,13 @@
* @return a single character used for escaping.
*/
char escapeCharacter() default '\\';

/**
* Configures the {@link QueryEnhancerSelector} to select a query enhancer for query introspection and transformation.
*
* @return a {@link QueryEnhancerSelector} class providing a no-args constructor.
* @since 4.0
*/
Class<? extends QueryEnhancerSelector> queryEnhancerSelector() default QueryEnhancerSelector.DefaultQueryEnhancerSelector.class;

}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSo
}
builder.addPropertyValue(ESCAPE_CHARACTER_PROPERTY, getEscapeCharacter(source).orElse('\\'));
builder.addPropertyReference("mappingContext", JPA_MAPPING_CONTEXT_BEAN_NAME);

if (source instanceof AnnotationRepositoryConfigurationSource) {
builder.addPropertyValue("queryEnhancerSelector",
source.getAttribute("queryEnhancerSelector", Class.class).orElse(null));
}
}

@Override
Expand Down
Loading