From 899b8b0db3d40603488ad50f116ab9e68021ba35 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 28 Mar 2019 16:51:43 +0100 Subject: [PATCH] DATAJPA-1519 - Polishing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moved the registration of the escape(…) SpEL function into an EvaluationContextExtension to avoid the need for a dedicated static method on EscapeCharacter. Moved Escape Character in the ….repository.query package to remove the package cycle. --- .../config/JpaRepositoryConfigExtension.java | 28 +++++++- .../{support => query}/EscapeCharacter.java | 31 +++++---- .../jpa/repository/query/JpaQueryCreator.java | 1 - .../query/JpaQueryLookupStrategy.java | 1 - .../query/ParameterMetadataProvider.java | 1 - .../repository/query/PartTreeJpaQuery.java | 1 - .../query/QueryParameterSetterFactory.java | 6 -- .../JpaEvaluationContextExtension.java | 57 ++++++++++++++++ .../support/JpaRepositoryFactory.java | 1 + .../support/JpaRepositoryFactoryBean.java | 1 + src/main/resources/META-INF/spring.schemas | 3 +- .../jpa/repository/config/spring-jpa-1.11.xsd | 65 +++++++++++++++++++ .../JpaCountQueryCreatorIntegrationTests.java | 1 - .../JpaQueryLookupStrategyUnitTests.java | 1 - .../ParameterExpressionProviderTests.java | 1 - ...meterMetadataProviderIntegrationTests.java | 1 - .../ParameterMetadataProviderUnitTests.java | 1 - .../PartTreeJpaQueryIntegrationTests.java | 1 - .../jpa/repository/sample/UserRepository.java | 2 +- 19 files changed, 170 insertions(+), 34 deletions(-) rename src/main/java/org/springframework/data/jpa/repository/{support => query}/EscapeCharacter.java (58%) create mode 100644 src/main/java/org/springframework/data/jpa/repository/support/JpaEvaluationContextExtension.java create mode 100644 src/main/resources/org/springframework/data/jpa/repository/config/spring-jpa-1.11.xsd diff --git a/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java b/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java index 90cced9ab..b2a3802d8 100644 --- a/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java +++ b/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java @@ -45,6 +45,7 @@ import org.springframework.dao.annotation.PersistenceExceptionTranslationPostPro import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.support.DefaultJpaContext; import org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor; +import org.springframework.data.jpa.repository.support.JpaEvaluationContextExtension; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; @@ -76,6 +77,7 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi private static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager"; private static final String ENABLE_DEFAULT_TRANSACTIONS_ATTRIBUTE = "enableDefaultTransactions"; private static final String JPA_METAMODEL_CACHE_CLEANUP_CLASSNAME = "org.springframework.data.jpa.util.JpaMetamodelCacheCleanup"; + private static final String ESCAPE_CHARACTER_PROPERTY = "escapeCharacter"; /* * (non-Javadoc) @@ -132,17 +134,23 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi Optional transactionManagerRef = source.getAttribute("transactionManagerRef"); builder.addPropertyValue("transactionManager", transactionManagerRef.orElse(DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)); builder.addPropertyValue("entityManager", getEntityManagerBeanDefinitionFor(source, source.getSource())); - builder.addPropertyValue("escapeCharacter", getEscapeCharacter(source).orElse('\\')); + builder.addPropertyValue(ESCAPE_CHARACTER_PROPERTY, getEscapeCharacter(source).orElse('\\')); builder.addPropertyReference("mappingContext", JPA_MAPPING_CONTEXT_BEAN_NAME); } /** - * XML configurations do not support {@link Character} values. This method catches the exception thrown and returns an {@link Optional#empty()} instead. + * XML configurations do not support {@link Character} values. This method catches the exception thrown and returns an + * {@link Optional#empty()} instead. */ private static Optional getEscapeCharacter(RepositoryConfigurationSource source) { try { - return source.getAttribute("escapeCharacter", Character.class); + + return AnnotationRepositoryConfigurationSource.class.isInstance(source) // + ? Optional.ofNullable((Character) AnnotationRepositoryConfigurationSource.class.cast(source).getAttributes() + .get(ESCAPE_CHARACTER_PROPERTY)) // + : source.getAttribute(ESCAPE_CHARACTER_PROPERTY).map(it -> it.toCharArray()[0]); + } catch (IllegalArgumentException ___) { return Optional.empty(); } @@ -203,12 +211,26 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi registerIfNotAlreadyRegistered(contextDefinition, registry, JPA_CONTEXT_BEAN_NAME, source); registerIfNotAlreadyRegistered(new RootBeanDefinition(JPA_METAMODEL_CACHE_CLEANUP_CLASSNAME), registry, JPA_METAMODEL_CACHE_CLEANUP_CLASSNAME, source); + + // EvaluationContextExtension for JPA specific SpEL functions + + registerIfNotAlreadyRegistered(() -> { + + Object value = getEscapeCharacter(config).orElse('\\'); + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(JpaEvaluationContextExtension.class); + builder.addConstructorArgValue(value); + + return builder.getBeanDefinition(); + + }, registry, JpaEvaluationContextExtension.class.getName(), source); } /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getConfigurationInspectionClassLoader(org.springframework.core.io.ResourceLoader) */ + @Override protected ClassLoader getConfigurationInspectionClassLoader(ResourceLoader loader) { ClassLoader classLoader = loader.getClassLoader(); diff --git a/src/main/java/org/springframework/data/jpa/repository/support/EscapeCharacter.java b/src/main/java/org/springframework/data/jpa/repository/query/EscapeCharacter.java similarity index 58% rename from src/main/java/org/springframework/data/jpa/repository/support/EscapeCharacter.java rename to src/main/java/org/springframework/data/jpa/repository/query/EscapeCharacter.java index 21d9b107d..269fa44ae 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/EscapeCharacter.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/EscapeCharacter.java @@ -13,35 +13,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jpa.repository.support; +package org.springframework.data.jpa.repository.query; import lombok.Value; +import java.util.Arrays; +import java.util.List; + import org.springframework.util.Assert; /** - * A Value-class encapsulating an escape character for LIKE queries and the actually usage of it in escaping Strings. + * A value type encapsulating an escape character for LIKE queries and the actually usage of it in escaping + * {@link String}s. * * @author Jens Schauder + * @author Oliver Drotbohm */ @Value(staticConstructor = "of") public class EscapeCharacter { + + private static final List TO_REPLACE = Arrays.asList("_", "%"); + char value; + /** + * Escapes all special like characters ({@code _}, {@code %}) using the configured escape character. + * + * @param value must not be {@literal null}. + * @return + */ public String escape(String value) { Assert.notNull(value, "Value must be not null."); - return value.replace("_", value + "_").replace("%", value + "%"); - } - - // used for SpEL expressions - static String escape(String value, String escape) { - - Assert.hasText(escape, "escape must be a sinlge character String."); - char[] chars = escape.toCharArray(); - Assert.isTrue(chars.length == 1, "escape must be a single character String."); - - return EscapeCharacter.of(chars[0]).escape(value); + return TO_REPLACE.stream() // + .reduce(value, (it, character) -> it.replace(character, this.value + character)); } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java index 1e5955fce..76bd83c95 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java @@ -36,7 +36,6 @@ import javax.persistence.metamodel.SingularAttribute; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.query.ParameterMetadataProvider.ParameterMetadata; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.repository.query.parser.AbstractQueryCreator; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java index cbfa21869..3d87f946b 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java @@ -22,7 +22,6 @@ import javax.persistence.EntityManager; import org.springframework.data.jpa.provider.PersistenceProvider; import org.springframework.data.jpa.provider.QueryExtractor; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryMetadata; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java b/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java index 51e26cc83..06102bae9 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java @@ -27,7 +27,6 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.ParameterExpression; import org.springframework.data.jpa.provider.PersistenceProvider; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java index 9f628ee39..561c67e80 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java @@ -29,7 +29,6 @@ import org.springframework.data.jpa.provider.PersistenceProvider; import org.springframework.data.jpa.repository.query.JpaQueryExecution.DeleteExecution; import org.springframework.data.jpa.repository.query.JpaQueryExecution.ExistsExecution; import org.springframework.data.jpa.repository.query.ParameterMetadataProvider.ParameterMetadata; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java b/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java index f1923664f..ed97c6d85 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java @@ -15,7 +15,6 @@ */ package org.springframework.data.jpa.repository.query; -import java.lang.reflect.Method; import java.util.List; import java.util.function.Function; @@ -35,7 +34,6 @@ import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; /** * Encapsulates different strategies for the creation of a {@link QueryParameterSetter} from a {@link Query} and a @@ -177,11 +175,7 @@ abstract class QueryParameterSetterFactory { private Object evaluateExpression(Expression expression, Object[] values) { EvaluationContext context = evaluationContextProvider.getEvaluationContext(parameters, values); - Method escapeMethod = ReflectionUtils.findMethod(EscapeCharacter.class, "escape", String.class, String.class); - Assert.notNull(escapeMethod, "Escape method must not be null."); - - context.setVariable("escape", escapeMethod); return expression.getValue(context, Object.class); } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEvaluationContextExtension.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaEvaluationContextExtension.java new file mode 100644 index 000000000..686e430c2 --- /dev/null +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaEvaluationContextExtension.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019 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.support; + +import org.springframework.data.jpa.repository.query.EscapeCharacter; +import org.springframework.data.spel.spi.EvaluationContextExtension; + +/** + * {@link EvaluationContextExtension} to register {@link EscapeCharacter} as root object to essentially expose an + * {@code expose(…)} function to SpEL. + * + * @author Oliver Drotbohm + */ +public class JpaEvaluationContextExtension implements EvaluationContextExtension { + + private final EscapeCharacter character; + + /** + * Creates a new {@link JpaEvaluationContextExtension} for the given escape character. + * + * @param escapeCharacter the character to be used to escape parameters for LIKE expression. + */ + public JpaEvaluationContextExtension(char escapeCharacter) { + this.character = EscapeCharacter.of(escapeCharacter); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.spel.spi.EvaluationContextExtension#getExtensionId() + */ + @Override + public String getExtensionId() { + return "jpa"; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.spel.spi.EvaluationContextExtension#getRootObject() + */ + @Override + public Object getRootObject() { + return character; + } +} diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java index 5534d446d..b8ea7f4a4 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java @@ -30,6 +30,7 @@ import org.springframework.data.jpa.provider.PersistenceProvider; import org.springframework.data.jpa.provider.QueryExtractor; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.query.AbstractJpaQuery; +import org.springframework.data.jpa.repository.query.EscapeCharacter; import org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy; import org.springframework.data.jpa.repository.query.JpaQueryMethod; import org.springframework.data.jpa.util.JpaMetamodel; diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java index 2595d7999..4adea1549 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java @@ -22,6 +22,7 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport; +import org.springframework.data.jpa.repository.query.EscapeCharacter; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/src/main/resources/META-INF/spring.schemas b/src/main/resources/META-INF/spring.schemas index 7d65aa229..93521b27d 100644 --- a/src/main/resources/META-INF/spring.schemas +++ b/src/main/resources/META-INF/spring.schemas @@ -3,4 +3,5 @@ http\://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd=org/springfra http\://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd=org/springframework/data/jpa/repository/config/spring-jpa-1.2.xsd http\://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd=org/springframework/data/jpa/repository/config/spring-jpa-1.3.xsd http\://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd=org/springframework/data/jpa/repository/config/spring-jpa-1.8.xsd -http\://www.springframework.org/schema/data/jpa/spring-jpa.xsd=org/springframework/data/jpa/repository/config/spring-jpa-1.8.xsd +http\://www.springframework.org/schema/data/jpa/spring-jpa-1.11.xsd=org/springframework/data/jpa/repository/config/spring-jpa-1.11.xsd +http\://www.springframework.org/schema/data/jpa/spring-jpa.xsd=org/springframework/data/jpa/repository/config/spring-jpa-1.11.xsd diff --git a/src/main/resources/org/springframework/data/jpa/repository/config/spring-jpa-1.11.xsd b/src/main/resources/org/springframework/data/jpa/repository/config/spring-jpa-1.11.xsd new file mode 100644 index 000000000..093f57b60 --- /dev/null +++ b/src/main/resources/org/springframework/data/jpa/repository/config/spring-jpa-1.11.xsd @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreatorIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreatorIntegrationTests.java index 4e48330f2..e62b2168f 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreatorIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreatorIntegrationTests.java @@ -31,7 +31,6 @@ import org.springframework.data.jpa.domain.sample.Role; import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.provider.HibernateUtils; import org.springframework.data.jpa.provider.PersistenceProvider; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.AbstractRepositoryMetadata; 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 f038b8296..d0b95108c 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 @@ -35,7 +35,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.provider.QueryExtractor; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.NamedQueries; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ParameterExpressionProviderTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ParameterExpressionProviderTests.java index 12d86f00e..5cbfa5cbe 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ParameterExpressionProviderTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ParameterExpressionProviderTests.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.provider.PersistenceProvider; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.repository.query.DefaultParameters; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java index d3ffe80db..17b524b59 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java @@ -28,7 +28,6 @@ import org.junit.runner.RunWith; import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.provider.PersistenceProvider; import org.springframework.data.jpa.repository.query.ParameterMetadataProvider.ParameterMetadata; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.parser.Part; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderUnitTests.java index 4d79261d7..6796fedd7 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderUnitTests.java @@ -24,7 +24,6 @@ import javax.persistence.criteria.CriteriaBuilder; import org.junit.Test; import org.springframework.data.jpa.provider.PersistenceProvider; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.parser.Part; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java index d74575259..91d906f22 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java @@ -44,7 +44,6 @@ import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.provider.HibernateUtils; import org.springframework.data.jpa.provider.PersistenceProvider; import org.springframework.data.jpa.repository.Temporal; -import org.springframework.data.jpa.repository.support.EscapeCharacter; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index cce006b3d..a4216a539 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -557,7 +557,7 @@ public interface UserRepository List findByNamedQueryWithConstructorExpression(); // DATAJPA-1519 - @Query("select u from User u where u.firstname like %?#{#escape([0],'#')}% escape '#'") + @Query("select u from User u where u.firstname like %?#{escape([0])}% escape '\\'") List findContainingEscaped(String namePart); interface RolesAndFirstname {