Skip to content

Commit 4dda7f3

Browse files
committed
Polishing.
Avoid unconditional ConcurrentLruCache instances for each String-based query. See: #3310 Original pull request: #3321
1 parent f66e185 commit 4dda7f3

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

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

+48-10
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery {
5454
private final SpelExpressionParser parser;
5555
private final QueryParameterSetter.QueryMetadataCache metadataCache = new QueryParameterSetter.QueryMetadataCache();
5656
private final QueryRewriter queryRewriter;
57-
private ConcurrentLruCache<CachableQuery, String> queryCache = new ConcurrentLruCache<>(16, this::applySorting);
57+
private final QuerySortRewriter querySortRewriter;
5858
private final Lazy<ParameterBinder> countParameterBinder;
5959

6060
/**
@@ -102,6 +102,13 @@ public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, Stri
102102
this.parser = parser;
103103
this.queryRewriter = queryRewriter;
104104

105+
JpaParameters parameters = method.getParameters();
106+
if (parameters.hasPageableParameter() || parameters.hasSortParameter()) {
107+
this.querySortRewriter = new CachingQuerySortRewriter();
108+
} else {
109+
this.querySortRewriter = NoOpQuerySortRewriter.INSTANCE;
110+
}
111+
105112
Assert.isTrue(method.isNativeQuery() || !query.usesJdbcStyleParameters(),
106113
"JDBC style parameters (?) are not supported for JPA queries");
107114
}
@@ -110,7 +117,7 @@ public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, Stri
110117
public Query doCreateQuery(JpaParametersParameterAccessor accessor) {
111118

112119
Sort sort = accessor.getSort();
113-
String sortedQueryString = applySortingIfNecessary(query, sort);
120+
String sortedQueryString = querySortRewriter.getSorted(query, sort);
114121

115122
ResultProcessor processor = getQueryMethod().getResultProcessor().withDynamicProjection(accessor);
116123

@@ -123,10 +130,6 @@ public Query doCreateQuery(JpaParametersParameterAccessor accessor) {
123130
return parameterBinder.get().bindAndPrepare(query, metadata, accessor);
124131
}
125132

126-
protected String applySorting(DeclaredQuery query, Sort sort) {
127-
return queryCache.get(new CachableQuery(query, sort));
128-
}
129-
130133
@Override
131134
protected ParameterBinder createBinder() {
132135
return createBinder(query);
@@ -210,12 +213,46 @@ String applySorting(CachableQuery cachableQuery) {
210213
cachableQuery.getAlias());
211214
}
212215

213-
private String applySortingIfNecessary(DeclaredQuery query, Sort sort) {
216+
/**
217+
* Query Sort Rewriter interface.
218+
*/
219+
interface QuerySortRewriter {
220+
String getSorted(DeclaredQuery query, Sort sort);
221+
}
222+
223+
/**
224+
* No-op query rewriter.
225+
*/
226+
enum NoOpQuerySortRewriter implements QuerySortRewriter {
227+
INSTANCE;
228+
229+
public String getSorted(DeclaredQuery query, Sort sort) {
230+
231+
if (sort.isSorted()) {
232+
throw new UnsupportedOperationException("NoOpQueryCache does not support sorting");
233+
}
214234

215-
if (sort.isUnsorted()) {
216235
return query.getQueryString();
217236
}
218-
return applySorting(query, sort);
237+
}
238+
239+
/**
240+
* Caching variant of {@link QuerySortRewriter}.
241+
*/
242+
class CachingQuerySortRewriter implements QuerySortRewriter {
243+
244+
private final ConcurrentLruCache<CachableQuery, String> queryCache = new ConcurrentLruCache<>(16,
245+
AbstractStringBasedJpaQuery.this::applySorting);
246+
247+
@Override
248+
public String getSorted(DeclaredQuery query, Sort sort) {
249+
250+
if (sort.isUnsorted()) {
251+
return query.getQueryString();
252+
}
253+
254+
return queryCache.get(new CachableQuery(query, sort));
255+
}
219256
}
220257

221258
/**
@@ -227,7 +264,7 @@ private String applySortingIfNecessary(DeclaredQuery query, Sort sort) {
227264
*/
228265
static class CachableQuery {
229266

230-
private DeclaredQuery declaredQuery;
267+
private final DeclaredQuery declaredQuery;
231268
private final String queryString;
232269
private final Sort sort;
233270

@@ -246,6 +283,7 @@ Sort getSort() {
246283
return sort;
247284
}
248285

286+
@Nullable
249287
String getAlias() {
250288
return declaredQuery.getAlias();
251289
}

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
import org.springframework.util.ReflectionUtils;
5050

5151
/**
52+
* Unit tests for {@link AbstractStringBasedJpaQuery}.
53+
*
5254
* @author Christoph Strobl
5355
*/
54-
public class AbstractStringBasedJpaQueryUnitTests {
56+
class AbstractStringBasedJpaQueryUnitTests {
5557

5658
@Test // GH-3310
5759
void shouldNotAttemptToAppendSortIfNoSortArgumentPresent() {

0 commit comments

Comments
 (0)