|
37 | 37 | import org.springframework.data.repository.query.RepositoryQuery;
|
38 | 38 | import org.springframework.data.repository.query.SpelEvaluator;
|
39 | 39 | import org.springframework.data.repository.query.SpelQueryContext;
|
40 |
| -import org.springframework.data.repository.query.SpelQueryContext.SpelExtractor; |
41 | 40 | import org.springframework.lang.Nullable;
|
42 | 41 | import org.springframework.util.Assert;
|
43 | 42 | import org.springframework.util.StringUtils;
|
@@ -81,6 +80,11 @@ final class StringBasedNeo4jQuery extends AbstractNeo4jQuery {
|
81 | 80 | */
|
82 | 81 | private final SpelEvaluator spelEvaluator;
|
83 | 82 |
|
| 83 | + /** |
| 84 | + * An optional evaluator for a count query if such a query is present. |
| 85 | + */ |
| 86 | + private final Optional<SpelEvaluator> spelEvaluatorForCountQuery; |
| 87 | + |
84 | 88 | /**
|
85 | 89 | * Create a {@link StringBasedNeo4jQuery} for a query method that is annotated with {@link Query @Query}. The
|
86 | 90 | * annotation is expected to have a value.
|
@@ -156,8 +160,12 @@ private StringBasedNeo4jQuery(Neo4jOperations neo4jOperations, Neo4jMappingConte
|
156 | 160 |
|
157 | 161 | super(neo4jOperations, mappingContext, queryMethod, queryType);
|
158 | 162 |
|
159 |
| - SpelExtractor spelExtractor = SPEL_QUERY_CONTEXT.parse(cypherTemplate); |
160 |
| - this.spelEvaluator = new SpelEvaluator(evaluationContextProvider, queryMethod.getParameters(), spelExtractor); |
| 163 | + Parameters<?, ?> methodParameters = queryMethod.getParameters(); |
| 164 | + this.spelEvaluator = new SpelEvaluator( |
| 165 | + evaluationContextProvider, methodParameters, SPEL_QUERY_CONTEXT.parse(cypherTemplate)); |
| 166 | + this.spelEvaluatorForCountQuery = queryMethod.getQueryAnnotation() |
| 167 | + .map(Query::countQuery) |
| 168 | + .map(countQuery -> new SpelEvaluator(evaluationContextProvider, methodParameters, SPEL_QUERY_CONTEXT.parse(countQuery))); |
161 | 169 | }
|
162 | 170 |
|
163 | 171 | @Override
|
@@ -193,7 +201,6 @@ Map<String, Object> bindParameters(Neo4jParameterAccessor parameterAccessor, boo
|
193 | 201 | // Values from the parameter accessor can only get converted after evaluation
|
194 | 202 | for (Entry<String, Object> evaluatedParam : spelEvaluator.evaluate(parameterAccessor.getValues()).entrySet()) {
|
195 | 203 | Object value;
|
196 |
| - |
197 | 204 | if (evaluatedParam.getValue() instanceof LiteralReplacement) {
|
198 | 205 | value = evaluatedParam.getValue();
|
199 | 206 | } else {
|
@@ -224,11 +231,22 @@ Map<String, Object> bindParameters(Neo4jParameterAccessor parameterAccessor, boo
|
224 | 231 |
|
225 | 232 | @Override
|
226 | 233 | protected Optional<PreparedQuery<Long>> getCountQuery(Neo4jParameterAccessor parameterAccessor) {
|
227 |
| - |
228 |
| - return queryMethod.getQueryAnnotation().map(queryAnnotation -> |
229 |
| - PreparedQuery.queryFor(Long.class) |
230 |
| - .withCypherQuery(queryAnnotation.countQuery()) |
231 |
| - .withParameters(bindParameters(parameterAccessor, false, UnaryOperator.identity())).build()); |
| 234 | + return spelEvaluatorForCountQuery.map(SpelEvaluator::getQueryString) |
| 235 | + .map(countQuery -> { |
| 236 | + Map<String, Object> boundParameters = bindParameters(parameterAccessor, false, UnaryOperator.identity()); |
| 237 | + QueryContext queryContext = new QueryContext( |
| 238 | + queryMethod.getRepositoryName() + "." + queryMethod.getName(), |
| 239 | + countQuery, |
| 240 | + boundParameters |
| 241 | + ); |
| 242 | + |
| 243 | + replaceLiteralsIn(queryContext); |
| 244 | + |
| 245 | + return PreparedQuery.queryFor(Long.class) |
| 246 | + .withCypherQuery(queryContext.query) |
| 247 | + .withParameters(boundParameters) |
| 248 | + .build(); |
| 249 | + }); |
232 | 250 | }
|
233 | 251 |
|
234 | 252 | /**
|
|
0 commit comments