DATAJPA-1534 - Improved backward compatibility.
Incorporates review feedback by @mp911de.
This commit is contained in:
@@ -76,11 +76,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!");
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.lang.Nullable;
|
||||
@Value(staticConstructor = "of")
|
||||
public class EscapeCharacter {
|
||||
|
||||
public static final EscapeCharacter DEFAULT = EscapeCharacter.of('\\');
|
||||
private static final List<String> TO_REPLACE = Arrays.asList("_", "%");
|
||||
|
||||
char escapeCharacter;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor;
|
||||
|
||||
private EntityPathResolver entityPathResolver;
|
||||
private EscapeCharacter escapeCharacter = EscapeCharacter.of('\\');
|
||||
private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaRepositoryFactory}.
|
||||
|
||||
@@ -45,7 +45,7 @@ public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
|
||||
|
||||
private @Nullable EntityManager entityManager;
|
||||
private EntityPathResolver entityPathResolver;
|
||||
private EscapeCharacter escapeCharacter = EscapeCharacter.of('\\');
|
||||
private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.
|
||||
|
||||
@@ -42,5 +42,7 @@ public interface JpaRepositoryImplementation<T, ID> extends JpaRepository<T, ID>
|
||||
*
|
||||
* @param escapeCharacter Must not be {@literal null}.
|
||||
*/
|
||||
void setEscapeCharacter(EscapeCharacter escapeCharacter);
|
||||
default void setEscapeCharacter(EscapeCharacter escapeCharacter) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
|
||||
private final PersistenceProvider provider;
|
||||
|
||||
private @Nullable CrudMethodMetadata metadata;
|
||||
private EscapeCharacter escapeCharacter;
|
||||
private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleJpaRepository} to manage objects of the given {@link JpaEntityInformation}.
|
||||
|
||||
@@ -118,22 +118,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))
|
||||
.isEqualTo(truePredicate);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,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))
|
||||
.isEqualTo(dummyPredicate);
|
||||
verify(cb, times(1)).equal(any(Expression.class), eq("foo"));
|
||||
}
|
||||
@@ -157,7 +157,7 @@ public class QueryByExamplePredicateBuilderUnitTests {
|
||||
p.father = father;
|
||||
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.of('\\')))
|
||||
.isThrownBy(() -> QueryByExamplePredicateBuilder.getPredicate(root, cb, of(p), EscapeCharacter.DEFAULT))
|
||||
.withCauseInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("Unexpected path type");
|
||||
}
|
||||
@@ -169,7 +169,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))
|
||||
.isEqualTo(andPredicate);
|
||||
|
||||
verify(cb, times(1)).equal(any(Expression.class), eq("foo"));
|
||||
@@ -185,7 +185,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))
|
||||
.isEqualTo(orPredicate);
|
||||
|
||||
verify(cb, times(1)).or(ArgumentMatchers.any());
|
||||
@@ -204,7 +204,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('\\'));
|
||||
}
|
||||
@@ -223,7 +223,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('\\'));
|
||||
}
|
||||
@@ -241,7 +241,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('\\'));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -76,7 +76,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);
|
||||
|
||||
@@ -92,7 +92,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, Sort.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ParameterMetadataProviderIntegrationTests {
|
||||
simulateDiscoveredParametername(parameters);
|
||||
|
||||
return new ParameterMetadataProvider(em.getCriteriaBuilder(), parameters,
|
||||
PersistenceProvider.fromEntityManager(em), EscapeCharacter.of('\\'));
|
||||
PersistenceProvider.fromEntityManager(em), EscapeCharacter.DEFAULT);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "ConstantConditions" })
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ParameterMetadataProviderUnitTests {
|
||||
when(parameters.getBindableParameters().iterator()).thenReturn(Collections.emptyListIterator());
|
||||
|
||||
ParameterMetadataProvider metadataProvider = new ParameterMetadataProvider(builder, parameters,
|
||||
persistenceProvider, EscapeCharacter.of('\\'));
|
||||
persistenceProvider, EscapeCharacter.DEFAULT);
|
||||
|
||||
assertThatExceptionOfType(RuntimeException.class) //
|
||||
.isThrownBy(() -> metadataProvider.next(mock(Part.class))) //
|
||||
|
||||
@@ -81,7 +81,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", PageRequest.of(0, 1) });
|
||||
jpaQuery.createQuery(new Object[] { "Matthews", PageRequest.of(0, 1) });
|
||||
@@ -105,7 +105,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", PageRequest.of(0, 1) });
|
||||
|
||||
@@ -120,7 +120,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" });
|
||||
|
||||
@@ -131,7 +131,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" });
|
||||
|
||||
@@ -142,7 +142,7 @@ public class PartTreeJpaQueryIntegrationTests {
|
||||
public void isEmptyCollection() throws Exception {
|
||||
|
||||
JpaQueryMethod queryMethod = getQueryMethod("findByRolesIsEmpty");
|
||||
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.of('\\'));
|
||||
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT);
|
||||
|
||||
Query query = jpaQuery.createQuery(new Object[] {});
|
||||
|
||||
@@ -153,7 +153,7 @@ public class PartTreeJpaQueryIntegrationTests {
|
||||
public void isNotEmptyCollection() throws Exception {
|
||||
|
||||
JpaQueryMethod queryMethod = getQueryMethod("findByRolesIsNotEmpty");
|
||||
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.of('\\'));
|
||||
PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT);
|
||||
|
||||
Query query = jpaQuery.createQuery(new Object[] {});
|
||||
|
||||
@@ -164,7 +164,7 @@ public class PartTreeJpaQueryIntegrationTests {
|
||||
public void rejectsIsEmptyOnNonCollectionProperty() throws Exception {
|
||||
|
||||
JpaQueryMethod method = getQueryMethod("findByFirstnameIsEmpty");
|
||||
AbstractJpaQuery jpaQuery = new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.of('\\'));
|
||||
AbstractJpaQuery jpaQuery = new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.DEFAULT);
|
||||
|
||||
jpaQuery.createQuery(new Object[] { "Oliver" });
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public class PartTreeJpaQueryIntegrationTests {
|
||||
JpaQueryMethod method = getQueryMethod("findByFirstname");
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.of('\\'))) //
|
||||
.isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.DEFAULT)) //
|
||||
.withMessageContaining("findByFirstname") // the method being analyzed
|
||||
.withMessageContaining(" firstname ") // the property we are looking for
|
||||
.withMessageContaining("UserRepository"); // the repository
|
||||
@@ -187,7 +187,7 @@ public class PartTreeJpaQueryIntegrationTests {
|
||||
JpaQueryMethod method = getQueryMethod("findByNoSuchProperty", String.class);
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.of('\\'))) //
|
||||
.isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.DEFAULT)) //
|
||||
.withMessageContaining("findByNoSuchProperty") // the method being analyzed
|
||||
.withMessageContaining(" noSuchProperty ") // the property we are looking for
|
||||
.withMessageContaining("UserRepository"); // the repository
|
||||
@@ -203,7 +203,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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user