diff --git a/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java index d951d8140..697bfde1b 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java @@ -22,6 +22,7 @@ import javax.persistence.TypedQuery; import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.util.Assert; /** @@ -35,6 +36,7 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery { private final StringQuery query; private final StringQuery countQuery; private final EvaluationContextProvider evaluationContextProvider; + private final SpelExpressionParser parser; /** * Creates a new {@link AbstractStringBasedJpaQuery} from the given {@link JpaQueryMethod}, {@link EntityManager} and @@ -44,19 +46,22 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery { * @param em must not be {@literal null}. * @param queryString must not be {@literal null}. * @param evaluationContextProvider must not be {@literal null}. + * @param parser must not be {@literal null}. */ public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, String queryString, - EvaluationContextProvider evaluationContextProvider) { + EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) { super(method, em); Assert.hasText(queryString, "Query string must not be null or empty!"); Assert.notNull(evaluationContextProvider, "ExpressionEvaluationContextProvider must not be null!"); + Assert.notNull(parser, "Parser must not be null or empty!"); this.evaluationContextProvider = evaluationContextProvider; - this.query = new ExpressionBasedStringQuery(queryString, method.getEntityInformation()); + this.query = new ExpressionBasedStringQuery(queryString, method.getEntityInformation(), parser); this.countQuery = new StringQuery(method.getCountQuery() != null ? method.getCountQuery() : QueryUtils.createCountQueryFor(this.query.getQueryString(), method.getCountQueryProjection())); + this.parser = parser; } /* @@ -81,7 +86,7 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery { @Override protected ParameterBinder createBinder(Object[] values) { return new SpelExpressionStringQueryParameterBinder(getQueryMethod().getParameters(), values, query, - evaluationContextProvider); + evaluationContextProvider, parser); } /** diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionAwareParameterBinder.java b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionAwareParameterBinder.java deleted file mode 100644 index ea0f50feb..000000000 --- a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionAwareParameterBinder.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.jpa.repository.query; - -import org.springframework.data.repository.query.EvaluationContextProvider; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.Assert; - -/** - * A {@link ParameterBinder} that is able to detect and dynamically evaluate SpEL expression based parameters. - * - * @author Thomas Darimont - */ -class ExpressionAwareParameterBinder extends ParameterBinder { - - private final EvaluationContextProvider evaluationContextProvider; - - /** - * Creates a new {@literal ExpressionAwareParameterBinder}. - * - * @param parameters - * @param evaluationContextProvider must not be {@literal null}. - */ - public ExpressionAwareParameterBinder(JpaParameters parameters, EvaluationContextProvider evaluationContextProvider) { - this(parameters, new Object[0], evaluationContextProvider); - } - - /** - * Creates a new {@literal ExpressionAwareParameterBinder}. - * - * @param parameters - * @param values - * @param evaluationContextProvider must not be {@literal null}. - */ - public ExpressionAwareParameterBinder(JpaParameters parameters, Object[] values, - EvaluationContextProvider evaluationContextProvider) { - - super(parameters, values); - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - - this.evaluationContextProvider = evaluationContextProvider; - } - - /** - * Parses the given {@code expressionString} into a SpEL {@link Expression}. - * - * @param expressionString - * @return - */ - protected Expression parseExpressionString(String expressionString) { - return new SpelExpressionParser().parseExpression(expressionString); - } - - /** - * Evaluates the given {@code expressionString} as a SpEL {@link Expression}. - * - * @param expressionString - * @return - */ - protected Object evaluateExpression(String expressionString) { - return evaluateExpression(parseExpressionString(expressionString)); - } - - /** - * Evaluates the given SpEL {@link Expression}. - * - * @param expr - * @return - */ - protected Object evaluateExpression(Expression expr) { - return expr.getValue(getEvaluationContext(), Object.class); - } - - /** - * Returns the {@link StandardEvaluationContext} to use for evaluation. - * - * @return - */ - protected EvaluationContext getEvaluationContext() { - return evaluationContextProvider.getEvaluationContext(getParameters(), getValues()); - } -} diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java index ac8b54e66..84bb1725d 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java @@ -36,26 +36,32 @@ import org.springframework.util.Assert; class ExpressionBasedStringQuery extends StringQuery { private static final String ENTITY_NAME = "entityName"; + private static final String ENTITY_NAME_VARIABLE = "#" + ENTITY_NAME; + private static final String ENTITY_NAME_VARIABLE_EXPRESSION = "#{" + ENTITY_NAME_VARIABLE + "}"; /** * Creates a new {@link ExpressionBasedStringQuery} for the given query and {@link EntityMetadata}. * * @param query must not be {@literal null} or empty. * @param metadata must not be {@literal null}. + * @param parser must not be {@literal null}. */ - public ExpressionBasedStringQuery(String query, JpaEntityMetadata metadata) { - super(renderQueryIfExpressionOrReturnQuery(query, metadata)); + public ExpressionBasedStringQuery(String query, JpaEntityMetadata metadata, SpelExpressionParser parser) { + super(renderQueryIfExpressionOrReturnQuery(query, metadata, parser)); } /** * @param query, the query expression potentially containing a SpEL expression. Must not be {@literal null}.} * @param metadata the {@link JpaEntityMetadata} for the given entity. Must not be {@literal null}. + * @param parser Must not be {@literal null}. * @return */ - private static String renderQueryIfExpressionOrReturnQuery(String query, JpaEntityMetadata metadata) { + private static String renderQueryIfExpressionOrReturnQuery(String query, JpaEntityMetadata metadata, + SpelExpressionParser parser) { Assert.notNull(query, "query must not be null!"); Assert.notNull(metadata, "metadata must not be null!"); + Assert.notNull(parser, "parser must not be null!"); if (!containsExpression(query)) { return query; @@ -64,7 +70,6 @@ class ExpressionBasedStringQuery extends StringQuery { StandardEvaluationContext evalContext = new StandardEvaluationContext(); evalContext.setVariable(ENTITY_NAME, metadata.getEntityName()); - SpelExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression(query, ParserContext.TEMPLATE_EXPRESSION); Object result = expr.getValue(evalContext, String.class); @@ -72,6 +77,6 @@ class ExpressionBasedStringQuery extends StringQuery { } private static boolean containsExpression(String query) { - return query.contains("#{#" + ENTITY_NAME + "}"); + return query.contains(ENTITY_NAME_VARIABLE_EXPRESSION); } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryFactory.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryFactory.java index cbbd82a21..8d656851d 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryFactory.java @@ -23,6 +23,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.expression.spel.standard.SpelExpressionParser; /** * Factory to create the appropriate {@link RepositoryQuery} for a {@link JpaQueryMethod}. @@ -33,6 +34,11 @@ enum JpaQueryFactory { INSTANCE; + /** + * The {@link SpelExpressionParser} is shared between all created {@link RepositoryQuery}s. + */ + private final SpelExpressionParser PARSER = new SpelExpressionParser(); + private static final Logger LOG = LoggerFactory.getLogger(JpaQueryFactory.class); /** @@ -67,8 +73,8 @@ enum JpaQueryFactory { return null; } - return method.isNativeQuery() ? new NativeJpaQuery(method, em, queryString, evaluationContextProvider) : // - new SimpleJpaQuery(method, em, queryString, evaluationContextProvider); + return method.isNativeQuery() ? new NativeJpaQuery(method, em, queryString, evaluationContextProvider, PARSER) : // + new SimpleJpaQuery(method, em, queryString, evaluationContextProvider, PARSER); } /** diff --git a/src/main/java/org/springframework/data/jpa/repository/query/NativeJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/NativeJpaQuery.java index 2eddbab42..3b4693ca9 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/NativeJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/NativeJpaQuery.java @@ -21,6 +21,7 @@ import javax.persistence.Query; import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.expression.spel.standard.SpelExpressionParser; /** * {@link RepositoryQuery} implementation that inspects a {@link org.springframework.data.repository.query.QueryMethod} @@ -40,9 +41,9 @@ final class NativeJpaQuery extends AbstractStringBasedJpaQuery { * @param evaluationContextProvider */ public NativeJpaQuery(JpaQueryMethod method, EntityManager em, String queryString, - EvaluationContextProvider evaluationContextProvider) { + EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) { - super(method, em, queryString, evaluationContextProvider); + super(method, em, queryString, evaluationContextProvider, parser); Parameters parameters = method.getParameters(); boolean hasPagingOrSortingParameter = parameters.hasPageableParameter() || parameters.hasSortParameter(); diff --git a/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java index d1c31725c..2ee943f9a 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java @@ -20,6 +20,7 @@ import javax.persistence.Query; import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.expression.spel.standard.SpelExpressionParser; /** * {@link RepositoryQuery} implementation that inspects a {@link org.springframework.data.repository.query.QueryMethod} @@ -33,26 +34,30 @@ final class SimpleJpaQuery extends AbstractStringBasedJpaQuery { /** * Creates a new {@link SimpleJpaQuery} encapsulating the query annotated on the given {@link JpaQueryMethod}. - * - * @param method must not be {@literal null}. - * @param em must not be {@literal null}. + * + * @param method must not be {@literal null} + * @param em must not be {@literal null} + * @param evaluationContextProvider must not be {@literal null} + * @param parser must not be {@literal null} */ - public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, - EvaluationContextProvider evaluationContextProvider) { - this(method, em, method.getAnnotatedQuery(), evaluationContextProvider); + public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, EvaluationContextProvider evaluationContextProvider, + SpelExpressionParser parser) { + this(method, em, method.getAnnotatedQuery(), evaluationContextProvider, parser); } /** * Creates a new {@link SimpleJpaQuery} that encapsulates a simple query string. - * - * @param method must not be {@literal null}. - * @param em must not be {@literal null}. - * @param queryString must not be {@literal null} or empty. + * + * @param method must not be {@literal null} + * @param em must not be {@literal null} + * @param queryString must not be {@literal null} or empty + * @param evaluationContextProvider must not be {@literal null} + * @param parser must not be {@literal null} */ public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, String queryString, - EvaluationContextProvider evaluationContextProvider) { + EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) { - super(method, em, queryString, evaluationContextProvider); + super(method, em, queryString, evaluationContextProvider, parser); validateQuery(getQuery().getQueryString(), String.format("Validation failed for query for method %s!", method)); diff --git a/src/main/java/org/springframework/data/jpa/repository/query/SpelExpressionStringQueryParameterBinder.java b/src/main/java/org/springframework/data/jpa/repository/query/SpelExpressionStringQueryParameterBinder.java index 6bd016c1d..8f1560d73 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/SpelExpressionStringQueryParameterBinder.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/SpelExpressionStringQueryParameterBinder.java @@ -15,11 +15,17 @@ */ package org.springframework.data.jpa.repository.query; +import java.util.List; + import javax.persistence.Query; +import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter; import org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding; import org.springframework.data.repository.query.EvaluationContextProvider; +import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.Assert; /** @@ -30,6 +36,8 @@ import org.springframework.util.Assert; class SpelExpressionStringQueryParameterBinder extends StringQueryParameterBinder { private final StringQuery query; + private final EvaluationContextProvider evaluationContextProvider; + private final SpelExpressionParser parser; /** * Creates a new {@link SpelExpressionStringQueryParameterBinder}. @@ -38,18 +46,22 @@ class SpelExpressionStringQueryParameterBinder extends StringQueryParameterBinde * @param values must not be {@literal null} * @param query must not be {@literal null} * @param evaluationContextProvider must not be {@literal null} + * @param parser must not be {@literal null} */ public SpelExpressionStringQueryParameterBinder(JpaParameters parameters, Object[] values, StringQuery query, - EvaluationContextProvider evaluationContextProvider) { - - super(parameters, values, query, evaluationContextProvider); + EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) { + super(parameters, values, query); Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); + Assert.notNull(parser, "SpelExpressionParser must not be null!"); + this.evaluationContextProvider = evaluationContextProvider; this.query = query; + this.parser = parser; } - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.data.jpa.repository.query.ParameterBinder#bind(javax.persistence.Query) */ @Override @@ -83,11 +95,9 @@ class SpelExpressionStringQueryParameterBinder extends StringQueryParameterBinde jpaQuery.setParameter(binding.getPosition(), binding.prepare(value)); } } catch (IllegalArgumentException iae) { - /* - * Since Eclipse doesn't reliably report whether a query has parameters - * we simply try to set the parameters and ignore possible failures. - * - */ + + // Since Eclipse doesn't reliably report whether a query has parameters + // we simply try to set the parameters and ignore possible failures. } } } @@ -100,4 +110,62 @@ class SpelExpressionStringQueryParameterBinder extends StringQueryParameterBinde String className = jpaQuery.getClass().getName(); return className.startsWith("org.apache.openjpa") || className.startsWith("org.hibernate"); } + + /** + * Parses the given {@code expressionString} into a SpEL {@link Expression}. + * + * @param expressionString + * @return + */ + private Expression parseExpressionString(String expressionString) { + return parser.parseExpression(expressionString); + } + + /** + * Evaluates the given SpEL {@link Expression}. + * + * @param expr + * @return + */ + private Object evaluateExpression(Expression expr) { + return expr.getValue(getEvaluationContext(), Object.class); + } + + /** + * Returns the {@link StandardEvaluationContext} to use for evaluation. + * + * @return + */ + private EvaluationContext getEvaluationContext() { + return evaluationContextProvider.getEvaluationContext(getParameters(), getValues()); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.ParameterBinder#canBindParameter(org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter) + */ + @Override + protected boolean canBindParameter(JpaParameter parameter) { + + List parameterBindings = query.getParameterBindings(); + + // if no parameter bindings are present, we simply rely on the check in super. + if (parameterBindings.isEmpty()) { + return super.canBindParameter(parameter); + } + + // otherwise determine whether there are any non expression parameters left to be bound. + int expressionParameterCount = 0; + for (ParameterBinding binding : parameterBindings) { + + if (binding.isExpression()) { + expressionParameterCount++; + } + } + + boolean allParametersAreUsedInExpressions = parameterBindings.size() - expressionParameterCount == 0; + + // if all parameters are used in expressions, then we can skip their bindings now, since they'll get bound later. + return !allParametersAreUsedInExpressions && super.canBindParameter(parameter); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StringQueryParameterBinder.java b/src/main/java/org/springframework/data/jpa/repository/query/StringQueryParameterBinder.java index f78421900..b792d311a 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StringQueryParameterBinder.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StringQueryParameterBinder.java @@ -15,14 +15,11 @@ */ package org.springframework.data.jpa.repository.query; -import java.util.List; - import javax.persistence.Query; import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter; import org.springframework.data.jpa.repository.query.StringQuery.LikeParameterBinding; import org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding; -import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; import org.springframework.util.Assert; @@ -33,7 +30,7 @@ import org.springframework.util.Assert; * @author Oliver Gierke * @author Thomas Darimont */ -public class StringQueryParameterBinder extends ExpressionAwareParameterBinder { +public class StringQueryParameterBinder extends ParameterBinder { private final StringQuery query; @@ -44,12 +41,10 @@ public class StringQueryParameterBinder extends ExpressionAwareParameterBinder { * @param parameters must not be {@literal null}. * @param values must not be {@literal null}. * @param query must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. */ - public StringQueryParameterBinder(JpaParameters parameters, Object[] values, StringQuery query, - EvaluationContextProvider evaluationContextProvider) { + public StringQueryParameterBinder(JpaParameters parameters, Object[] values, StringQuery query) { - super(parameters, values, evaluationContextProvider); + super(parameters, values); Assert.notNull(query, "StringQuery must not be null!"); this.query = query; @@ -66,34 +61,6 @@ public class StringQueryParameterBinder extends ExpressionAwareParameterBinder { super.bind(jpaQuery, methodParameter, binding.prepare(value), position); } - /* (non-Javadoc) - * @see org.springframework.data.jpa.repository.query.ParameterBinder#canBindParameter(org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter) - */ - @Override - protected boolean canBindParameter(JpaParameter parameter) { - - List parameterBindings = query.getParameterBindings(); - - // if no parameter bindings are present, we simply rely on the check in super. - if (parameterBindings.isEmpty()) { - return super.canBindParameter(parameter); - } - - // otherwise determine whether there are any non expression parameters left to be bound. - int expressionParameterCount = 0; - for (ParameterBinding binding : parameterBindings) { - - if (binding.isExpression()) { - expressionParameterCount++; - } - } - - boolean allParametersAreUsedInExpressions = parameterBindings.size() - expressionParameterCount == 0; - - // if all parameters are used in expressions, then we can skip their bindings now, since they'll get bound later. - return !allParametersAreUsedInExpressions && super.canBindParameter(parameter); - } - /** * Finds the {@link LikeParameterBinding} to be applied before binding a parameter value to the query. * diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java index 07e756020..992aaad0e 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.expression.spel.standard.SpelExpressionParser; /** * Unit tests for {@link ExpressionBasedStringQuery}. @@ -35,6 +36,8 @@ public class ExpressionBasedStringQueryUnitTests { @Mock JpaEntityMetadata metadata; + static final SpelExpressionParser SPEL_PARSER = new SpelExpressionParser(); + /** * @see DATAJPA-170 */ @@ -44,7 +47,7 @@ public class ExpressionBasedStringQueryUnitTests { when(metadata.getEntityName()).thenReturn("User"); String source = "select from #{#entityName} u where u.firstname like :firstname"; - StringQuery query = new ExpressionBasedStringQuery(source, metadata); + StringQuery query = new ExpressionBasedStringQuery(source, metadata, SPEL_PARSER); assertThat(query.getQueryString(), is("select from User u where u.firstname like :firstname")); } @@ -56,7 +59,7 @@ public class ExpressionBasedStringQueryUnitTests { when(metadata.getEntityName()).thenReturn("User"); - StringQuery query = new ExpressionBasedStringQuery("select u from #{#entityName} u", metadata); + StringQuery query = new ExpressionBasedStringQuery("select u from #{#entityName} u", metadata, SPEL_PARSER); assertThat(query.getAlias(), is("u")); assertThat(query.getQueryString(), is("select u from User u")); } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategyUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategyUnitTests.java index aed61b6d9..778c48bb2 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategyUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategyUnitTests.java @@ -41,8 +41,9 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.DefaultEvaluationContextProvider; +import org.springframework.data.repository.query.EvaluationContextProvider; +import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; /** @@ -54,6 +55,7 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key; @RunWith(MockitoJUnitRunner.class) public class JpaQueryLookupStrategyUnitTests { + private static final EvaluationContextProvider EVALUATION_CONTEXT_PROVIDER = DefaultEvaluationContextProvider.INSTANCE; @Mock EntityManager em; @Mock EntityManagerFactory emf; @Mock QueryExtractor extractor; @@ -75,7 +77,7 @@ public class JpaQueryLookupStrategyUnitTests { public void invalidAnnotatedQueryCausesException() throws Exception { QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, Key.CREATE_IF_NOT_FOUND, extractor, - DefaultEvaluationContextProvider.INSTANCE); + EVALUATION_CONTEXT_PROVIDER); Method method = UserRepository.class.getMethod("findByFoo", String.class); RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); @@ -97,7 +99,7 @@ public class JpaQueryLookupStrategyUnitTests { public void sholdThrowMorePreciseExceptionIfTryingToUsePaginationInNativeQueries() throws Exception { QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, Key.CREATE_IF_NOT_FOUND, extractor, - DefaultEvaluationContextProvider.INSTANCE); + EVALUATION_CONTEXT_PROVIDER); Method method = UserRepository.class.getMethod("findByInvalidNativeQuery", String.class, Pageable.class); RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); diff --git a/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java index 1d611115c..5157b3781 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java @@ -44,8 +44,10 @@ import org.springframework.data.jpa.provider.QueryExtractor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.sample.UserRepository; import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.DefaultEvaluationContextProvider; +import org.springframework.data.repository.query.EvaluationContextProvider; +import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.expression.spel.standard.SpelExpressionParser; /** * Unit test for {@link SimpleJpaQuery}. @@ -57,6 +59,8 @@ import org.springframework.data.repository.query.DefaultEvaluationContextProvide public class SimpleJpaQueryUnitTests { static final String USER_QUERY = "select u from User u"; + static final SpelExpressionParser PARSER = new SpelExpressionParser(); + private static final EvaluationContextProvider EVALUATION_CONTEXT_PROVIDER = DefaultEvaluationContextProvider.INSTANCE; JpaQueryMethod method; @@ -95,8 +99,8 @@ public class SimpleJpaQueryUnitTests { when(method.getEntityInformation()).thenReturn((JpaEntityMetadata) new DefaultJpaEntityMetadata(User.class)); when(em.createQuery("foo", Long.class)).thenReturn(query); - SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "select u from User u", - DefaultEvaluationContextProvider.INSTANCE); + SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "select u from User u", EVALUATION_CONTEXT_PROVIDER, + PARSER); assertThat(jpaQuery.createCountQuery(new Object[] {}), is(query)); } @@ -113,7 +117,7 @@ public class SimpleJpaQueryUnitTests { JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor); AbstractJpaQuery jpaQuery = new SimpleJpaQuery(queryMethod, em, "select u from User u", - DefaultEvaluationContextProvider.INSTANCE); + EVALUATION_CONTEXT_PROVIDER, PARSER); jpaQuery.createCountQuery(new Object[] { new PageRequest(1, 10) }); verify(query, times(0)).setFirstResult(anyInt()); @@ -127,7 +131,7 @@ public class SimpleJpaQueryUnitTests { Method method = SampleRepository.class.getMethod("findNativeByLastname", String.class); JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor); AbstractJpaQuery jpaQuery = JpaQueryFactory.INSTANCE.fromQueryAnnotation(queryMethod, em, - DefaultEvaluationContextProvider.INSTANCE); + EVALUATION_CONTEXT_PROVIDER); assertThat(jpaQuery instanceof NativeJpaQuery, is(true)); @@ -208,8 +212,7 @@ public class SimpleJpaQueryUnitTests { private RepositoryQuery createJpaQuery(Method method) { JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor); - return JpaQueryFactory.INSTANCE.fromQueryAnnotation(queryMethod, em, - DefaultEvaluationContextProvider.INSTANCE); + return JpaQueryFactory.INSTANCE.fromQueryAnnotation(queryMethod, em, EVALUATION_CONTEXT_PROVIDER); } interface SampleRepository {