Skip to content

Commit 5f244c4

Browse files
mp911degregturn
authored andcommitted
Delay count query derivation.
We now delay the count query creation to the actual time when we need the count query to avoid query creation of invalid queries (e.g. count queries for DELETE or UPDATE statements). See #2812
1 parent 45b24ad commit 5f244c4

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

Diff for: spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java

+10-11
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@
1818
import jakarta.persistence.EntityManager;
1919
import jakarta.persistence.Query;
2020

21-
import org.apache.commons.logging.Log;
22-
import org.apache.commons.logging.LogFactory;
23-
2421
import org.springframework.data.domain.Pageable;
2522
import org.springframework.data.domain.Sort;
2623
import org.springframework.data.jpa.repository.QueryRewriter;
2724
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
2825
import org.springframework.data.repository.query.ResultProcessor;
2926
import org.springframework.data.repository.query.ReturnedType;
27+
import org.springframework.data.util.Lazy;
3028
import org.springframework.expression.spel.standard.SpelExpressionParser;
3129
import org.springframework.lang.Nullable;
3230
import org.springframework.util.Assert;
@@ -46,7 +44,7 @@
4644
abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery {
4745

4846
private final DeclaredQuery query;
49-
private final DeclaredQuery countQuery;
47+
private final Lazy<DeclaredQuery> countQuery;
5048
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
5149
private final SpelExpressionParser parser;
5250
private final QueryParameterSetter.QueryMetadataCache metadataCache = new QueryParameterSetter.QueryMetadataCache();
@@ -65,8 +63,8 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery {
6563
* @param queryRewriter must not be {@literal null}.
6664
*/
6765
public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, String queryString,
68-
@Nullable String countQueryString, QueryRewriter queryRewriter, QueryMethodEvaluationContextProvider evaluationContextProvider,
69-
SpelExpressionParser parser) {
66+
@Nullable String countQueryString, QueryRewriter queryRewriter,
67+
QueryMethodEvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) {
7068

7169
super(method, em);
7270

@@ -79,9 +77,10 @@ public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, Stri
7977
this.query = new ExpressionBasedStringQuery(queryString, method.getEntityInformation(), parser,
8078
method.isNativeQuery());
8179

82-
DeclaredQuery countQuery = query.deriveCountQuery(countQueryString, method.getCountQueryProjection());
83-
this.countQuery = ExpressionBasedStringQuery.from(countQuery, method.getEntityInformation(), parser,
84-
method.isNativeQuery());
80+
this.countQuery = Lazy.of(() -> {
81+
DeclaredQuery countQuery = query.deriveCountQuery(countQueryString, method.getCountQueryProjection());
82+
return ExpressionBasedStringQuery.from(countQuery, method.getEntityInformation(), parser, method.isNativeQuery());
83+
});
8584

8685
this.parser = parser;
8786
this.queryRewriter = queryRewriter;
@@ -117,7 +116,7 @@ protected ParameterBinder createBinder() {
117116
@Override
118117
protected Query doCreateCountQuery(JpaParametersParameterAccessor accessor) {
119118

120-
String queryString = countQuery.getQueryString();
119+
String queryString = countQuery.get().getQueryString();
121120
EntityManager em = getEntityManager();
122121

123122
Query query = getQueryMethod().isNativeQuery() //
@@ -142,7 +141,7 @@ public DeclaredQuery getQuery() {
142141
* @return the countQuery
143142
*/
144143
public DeclaredQuery getCountQuery() {
145-
return countQuery;
144+
return countQuery.get();
146145
}
147146

148147
/**

0 commit comments

Comments
 (0)