DATAJPA-1534 - Improved backward compatibility.

Incorporates review feedback by @mp911de.
This commit is contained in:
Jens Schauder
2019-04-29 15:13:22 +02:00
parent 33027dc370
commit 2ef1b156a7
12 changed files with 45 additions and 29 deletions

View File

@@ -72,11 +72,23 @@ public class QueryByExamplePredicateBuilder {
* @param root must not be {@literal null}.
* @param cb must not be {@literal null}.
* @param example must not be {@literal null}.
* @param escapeCharacter
* @return never {@literal null}.
*/
public static <T> Predicate getPredicate(Root<T> root, CriteriaBuilder cb, Example<T> example) {
return getPredicate(root, cb, example, EscapeCharacter.DEFAULT);
}
/**
* Extract the {@link Predicate} representing the {@link Example}.
*
* @param root must not be {@literal null}.
* @param cb must not be {@literal null}.
* @param example must not be {@literal null}.
* @param escapeCharacter Must not be {@literal null}.
* @return never {@literal null}.
*/
public static <T> Predicate getPredicate(Root<T> root, CriteriaBuilder cb, Example<T> example,
EscapeCharacter escapeCharacter) {
EscapeCharacter escapeCharacter) {
Assert.notNull(root, "Root must not be null!");
Assert.notNull(cb, "CriteriaBuilder must not be null!");

View File

@@ -18,6 +18,7 @@ package org.springframework.data.jpa.repository.query;
import lombok.Value;
import java.util.Arrays;
import java.util.List;
/**
* A value type encapsulating an escape character for LIKE queries and the actually usage of it in escaping
@@ -29,6 +30,9 @@ import java.util.Arrays;
@Value(staticConstructor = "of")
public class EscapeCharacter {
public static final EscapeCharacter DEFAULT = EscapeCharacter.of('\\');
private static final List<String> TO_REPLACE = Arrays.asList("_", "%");
char escapeCharacter;
/**

View File

@@ -59,7 +59,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
private final QueryExtractor extractor;
private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor;
private EscapeCharacter escapeCharacter = EscapeCharacter.of('\\');
private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
/**
* Creates a new {@link JpaRepositoryFactory}.

View File

@@ -39,7 +39,7 @@ public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
private EntityManager entityManager;
private EscapeCharacter escapeCharacter = EscapeCharacter.of('\\');
private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
/**
* Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.

View File

@@ -84,7 +84,7 @@ public class SimpleJpaRepository<T, ID extends Serializable>
private final PersistenceProvider provider;
private CrudMethodMetadata metadata;
private EscapeCharacter escapeCharacter;
private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
/**
* Creates a new {@link SimpleJpaRepository} to manage objects of the given {@link JpaEntityInformation}.

View File

@@ -120,22 +120,22 @@ public class QueryByExamplePredicateBuilderUnitTests {
@Test(expected = IllegalArgumentException.class) // DATAJPA-218
public void getPredicateShouldThrowExceptionOnNullRoot() {
QueryByExamplePredicateBuilder.getPredicate(null, cb, of(new Person()), EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(null, cb, of(new Person()), EscapeCharacter.DEFAULT);
}
@Test(expected = IllegalArgumentException.class) // DATAJPA-218
public void getPredicateShouldThrowExceptionOnNullCriteriaBuilder() {
QueryByExamplePredicateBuilder.getPredicate(root, null, of(new Person()), EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(root, null, of(new Person()), EscapeCharacter.DEFAULT);
}
@Test(expected = IllegalArgumentException.class) // DATAJPA-218
public void getPredicateShouldThrowExceptionOnNullExample() {
QueryByExamplePredicateBuilder.getPredicate(root, null, null, EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(root, null, null, EscapeCharacter.DEFAULT);
}
@Test // DATAJPA-218
public void emptyCriteriaListShouldResultTruePredicate() {
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, of(new Person()), EscapeCharacter.of('\\')),
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, of(new Person()), EscapeCharacter.DEFAULT),
equalTo(truePredicate));
}
@@ -145,7 +145,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
Person p = new Person();
p.firstname = "foo";
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.of('\\')),
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.DEFAULT),
equalTo(dummyPredicate));
verify(cb, times(1)).equal(any(Expression.class), eq("foo"));
}
@@ -161,7 +161,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
exception.expectCause(IsInstanceOf.<Throwable> instanceOf(IllegalArgumentException.class));
exception.expectMessage("Unexpected path type");
QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.DEFAULT);
}
@Test // DATAJPA-218
@@ -171,7 +171,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
p.firstname = "foo";
p.age = 2L;
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.of('\\')),
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.DEFAULT),
equalTo(andPredicate));
verify(cb, times(1)).equal(any(Expression.class), eq("foo"));
@@ -187,7 +187,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
Example<Person> example = of(person, ExampleMatcher.matchingAny());
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.of('\\')),
assertThat(QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.DEFAULT),
equalTo(orPredicate));
verify(cb, times(1)).or(Matchers.<Predicate>anyVararg());
@@ -206,7 +206,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //
);
QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.DEFAULT);
verify(cb, times(1)).like(any(Expression.class), eq("%f\\\\o\\_o%"), eq('\\'));
}
@@ -225,7 +225,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
.withStringMatcher(ExampleMatcher.StringMatcher.STARTING) //
);
QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.DEFAULT);
verify(cb, times(1)).like(any(Expression.class), eq("f\\\\o\\_o%"), eq('\\'));
}
@@ -243,7 +243,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
.withStringMatcher(ExampleMatcher.StringMatcher.ENDING) //
);
QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.of('\\'));
QueryByExamplePredicateBuilder.getPredicate(root, cb, example, EscapeCharacter.DEFAULT);
verify(cb, times(1)).like(any(Expression.class), eq("%f\\\\o\\_o"), eq('\\'));
}

View File

@@ -60,7 +60,7 @@ public class JpaCountQueryCreatorIntegrationTests {
PartTree tree = new PartTree("findDistinctByRolesIn", User.class);
ParameterMetadataProvider metadataProvider = new ParameterMetadataProvider(entityManager.getCriteriaBuilder(),
queryMethod.getParameters(), provider, EscapeCharacter.of('\\'));
queryMethod.getParameters(), provider, EscapeCharacter.DEFAULT);
JpaCountQueryCreator creator = new JpaCountQueryCreator(tree, queryMethod.getResultProcessor().getReturnedType(),
entityManager.getCriteriaBuilder(), metadataProvider);

View File

@@ -50,7 +50,7 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key;
/**
* Unit tests for {@link JpaQueryLookupStrategy}.
*
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
@@ -80,7 +80,7 @@ public class JpaQueryLookupStrategyUnitTests {
public void invalidAnnotatedQueryCausesException() throws Exception {
QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, Key.CREATE_IF_NOT_FOUND, extractor,
EVALUATION_CONTEXT_PROVIDER, EscapeCharacter.of('\\'));
EVALUATION_CONTEXT_PROVIDER, EscapeCharacter.DEFAULT);
Method method = UserRepository.class.getMethod("findByFoo", String.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);
@@ -99,7 +99,7 @@ public class JpaQueryLookupStrategyUnitTests {
public void sholdThrowMorePreciseExceptionIfTryingToUsePaginationInNativeQueries() throws Exception {
QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, Key.CREATE_IF_NOT_FOUND, extractor,
EVALUATION_CONTEXT_PROVIDER, EscapeCharacter.of('\\'));
EVALUATION_CONTEXT_PROVIDER, EscapeCharacter.DEFAULT);
Method method = UserRepository.class.getMethod("findByInvalidNativeQuery", String.class, Pageable.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);

View File

@@ -58,7 +58,7 @@ public class ParameterExpressionProviderTests {
CriteriaBuilder builder = em.getCriteriaBuilder();
PersistenceProvider persistenceProvider = PersistenceProvider.fromEntityManager(em);
ParameterMetadataProvider provider = new ParameterMetadataProvider(builder, accessor, persistenceProvider, EscapeCharacter.of('\\'));
ParameterMetadataProvider provider = new ParameterMetadataProvider(builder, accessor, persistenceProvider, EscapeCharacter.DEFAULT);
ParameterExpression<? extends Comparable> expression = provider.next(part, Comparable.class).getExpression();
assertThat(expression.getParameterType(), is(typeCompatibleWith(int.class)));
}

View File

@@ -81,7 +81,7 @@ public class ParameterMetadataProviderIntegrationTests {
simulateDiscoveredParametername(parameters, 0, "name");
return new ParameterMetadataProvider(em.getCriteriaBuilder(), parameters,
PersistenceProvider.fromEntityManager(em), EscapeCharacter.of('\\'));
PersistenceProvider.fromEntityManager(em), EscapeCharacter.DEFAULT);
}
@SuppressWarnings("unchecked")

View File

@@ -44,7 +44,7 @@ public class ParameterMetadataProviderUnitTests {
Parameters<?, ?> parameters = mock(Parameters.class, RETURNS_DEEP_STUBS);
ParameterMetadataProvider metadataProvider = new ParameterMetadataProvider(builder, parameters,
persistenceProvider, EscapeCharacter.of('\\'));
persistenceProvider, EscapeCharacter.DEFAULT);
exception.expect(IllegalArgumentException.class);
exception.expectMessage("parameter");

View File

@@ -54,7 +54,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Integration tests for {@link PartTreeJpaQuery}.
*
*
* @author Oliver Gierke
* @author Mark Paluch
*/
@@ -79,7 +79,7 @@ public class PartTreeJpaQueryIntegrationTests {
public void test() throws Exception {
JpaQueryMethod queryMethod = getQueryMethod("findByFirstname", String.class, Pageable.class);
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.of('\\'));
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT);
jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) });
jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) });
@@ -103,7 +103,7 @@ public class PartTreeJpaQueryIntegrationTests {
public void recreatesQueryIfNullValueIsGiven() throws Exception {
JpaQueryMethod queryMethod = getQueryMethod("findByFirstname", String.class, Pageable.class);
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.of('\\'));
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT);
Query query = jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) });
@@ -118,7 +118,7 @@ public class PartTreeJpaQueryIntegrationTests {
public void shouldLimitExistsProjectionQueries() throws Exception {
JpaQueryMethod queryMethod = getQueryMethod("existsByFirstname", String.class);
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.of('\\'));
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT);
Query query = jpaQuery.createQuery(new Object[] { "Matthews" });
@@ -129,7 +129,7 @@ public class PartTreeJpaQueryIntegrationTests {
public void shouldSelectAliasedIdForExistsProjectionQueries() throws Exception {
JpaQueryMethod queryMethod = getQueryMethod("existsByFirstname", String.class);
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.of('\\'));
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT);
Query query = jpaQuery.createQuery(new Object[] { "Matthews" });
@@ -172,7 +172,7 @@ public class PartTreeJpaQueryIntegrationTests {
JpaQueryMethod queryMethod = getQueryMethod(methodName, parameterTypes);
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager,
PersistenceProvider.fromEntityManager(entityManager), EscapeCharacter.of('\\'));
PersistenceProvider.fromEntityManager(entityManager), EscapeCharacter.DEFAULT);
jpaQuery.createQuery(values);
}