|
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