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 30fdcca99..def656f32 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 @@ -37,7 +37,7 @@ import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.Part.Type; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.repository.query.parser.PartTree.OrPart; +import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; /** @@ -62,12 +62,25 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { /** * Creates a new {@link PartTreeJpaQuery}. + * + * @param method must not be {@literal null}. + * @param em must not be {@literal null}. + * @param persistenceProvider must not be {@literal null}. + */ + PartTreeJpaQuery(JpaQueryMethod method, EntityManager em, PersistenceProvider persistenceProvider) { + this(method, em, persistenceProvider, EscapeCharacter.DEFAULT); + } + + /** + * Creates a new {@link PartTreeJpaQuery}. + * * @param method must not be {@literal null}. * @param em must not be {@literal null}. * @param persistenceProvider must not be {@literal null}. * @param escape */ - PartTreeJpaQuery(JpaQueryMethod method, EntityManager em, PersistenceProvider persistenceProvider, EscapeCharacter escape) { + PartTreeJpaQuery(JpaQueryMethod method, EntityManager em, PersistenceProvider persistenceProvider, + EscapeCharacter escape) { super(method, em); @@ -130,18 +143,17 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { int argCount = 0; - for (OrPart orPart : tree) { + Iterable parts = () -> tree.stream().flatMap(Streamable::stream).iterator(); - for (Part part : orPart) { + for (Part part : parts) { - int numberOfArguments = part.getNumberOfArguments(); + int numberOfArguments = part.getNumberOfArguments(); - for (int i = 0; i < numberOfArguments; i++) { + for (int i = 0; i < numberOfArguments; i++) { - throwExceptionOnArgumentMismatch(methodName, part, parameters, argCount); + throwExceptionOnArgumentMismatch(methodName, part, parameters, argCount); - argCount++; - } + argCount++; } } } @@ -154,7 +166,7 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { if (!parameters.getBindableParameters().hasParameterAt(index)) { throw new IllegalStateException(String.format( - "For the method %s we expect at least %d arguments but only found %d. This leaves an operator of type %s for property %s unbound.", + "Method %s expects at least %d arguments but only found %d. This leaves an operator of type %s for property %s unbound.", methodName, index + 1, index, type.name(), property)); } @@ -168,15 +180,10 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { } private static String wrongParameterTypeMessage(String methodName, String property, Type operatorType, - String expectedArgumenType, JpaParameter parameter) { + String expectedArgumentType, JpaParameter parameter) { - return String.format( // - "The operator %s on %s requires a %s argument, but we found %s in method %s", // - operatorType.name(), // - property, expectedArgumenType, // - parameter.getType(), // - methodName // - ); + return String.format("Operator %s on %s requires a %s argument, found %s in method %s.", operatorType.name(), + property, expectedArgumentType, parameter.getType(), methodName); } private static boolean parameterIsCollectionLike(JpaParameter parameter) { 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 97e03bc49..0911c76b3 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 @@ -32,13 +32,13 @@ import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TemporalType; -import org.assertj.core.api.Assertions; import org.hibernate.Version; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -83,7 +83,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.DEFAULT); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider); jpaQuery.createQuery(new Object[] { "Matthews", PageRequest.of(0, 1) }); jpaQuery.createQuery(new Object[] { "Matthews", PageRequest.of(0, 1) }); @@ -107,7 +107,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.DEFAULT); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider); Query query = jpaQuery.createQuery(new Object[] { "Matthews", PageRequest.of(0, 1) }); @@ -122,7 +122,7 @@ public class PartTreeJpaQueryIntegrationTests { public void shouldLimitExistsProjectionQueries() throws Exception { JpaQueryMethod queryMethod = getQueryMethod("existsByFirstname", String.class); - PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider); Query query = jpaQuery.createQuery(new Object[] { "Matthews" }); @@ -133,7 +133,7 @@ public class PartTreeJpaQueryIntegrationTests { public void shouldSelectAliasedIdForExistsProjectionQueries() throws Exception { JpaQueryMethod queryMethod = getQueryMethod("existsByFirstname", String.class); - PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider); Query query = jpaQuery.createQuery(new Object[] { "Matthews" }); @@ -144,7 +144,7 @@ public class PartTreeJpaQueryIntegrationTests { public void isEmptyCollection() throws Exception { JpaQueryMethod queryMethod = getQueryMethod("findByRolesIsEmpty"); - PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider); Query query = jpaQuery.createQuery(new Object[] {}); @@ -155,7 +155,7 @@ public class PartTreeJpaQueryIntegrationTests { public void isNotEmptyCollection() throws Exception { JpaQueryMethod queryMethod = getQueryMethod("findByRolesIsNotEmpty"); - PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider, EscapeCharacter.DEFAULT); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, provider); Query query = jpaQuery.createQuery(new Object[] {}); @@ -166,7 +166,7 @@ public class PartTreeJpaQueryIntegrationTests { public void rejectsIsEmptyOnNonCollectionProperty() throws Exception { JpaQueryMethod method = getQueryMethod("findByFirstnameIsEmpty"); - AbstractJpaQuery jpaQuery = new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.DEFAULT); + AbstractJpaQuery jpaQuery = new PartTreeJpaQuery(method, entityManager, provider); jpaQuery.createQuery(new Object[] { "Oliver" }); } @@ -176,7 +176,7 @@ public class PartTreeJpaQueryIntegrationTests { JpaQueryMethod method = getQueryMethod("findByIdIn", Long.class); - Assertions.assertThatExceptionOfType(RuntimeException.class) // + assertThatExceptionOfType(RuntimeException.class) // .isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider)) // .withMessageContaining("findByIdIn") // .withMessageContaining(" IN ") // @@ -189,7 +189,7 @@ public class PartTreeJpaQueryIntegrationTests { JpaQueryMethod method = getQueryMethod("findById", Collection.class); - Assertions.assertThatExceptionOfType(RuntimeException.class) // + assertThatExceptionOfType(RuntimeException.class) // .isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider)) // .withMessageContaining("findById") // .withMessageContaining(" SIMPLE_PROPERTY ") // @@ -203,7 +203,7 @@ public class PartTreeJpaQueryIntegrationTests { JpaQueryMethod method = getQueryMethod("findByFirstname"); assertThatExceptionOfType(IllegalArgumentException.class) // - .isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.DEFAULT)) // + .isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider)) // .withMessageContaining("findByFirstname") // the method being analyzed .withMessageContaining(" firstname ") // the property we are looking for .withMessageContaining("UserRepository"); // the repository @@ -215,7 +215,7 @@ public class PartTreeJpaQueryIntegrationTests { JpaQueryMethod method = getQueryMethod("findByNoSuchProperty", String.class); assertThatExceptionOfType(IllegalArgumentException.class) // - .isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider, EscapeCharacter.DEFAULT)) // + .isThrownBy(() -> new PartTreeJpaQuery(method, entityManager, provider)) // .withMessageContaining("findByNoSuchProperty") // the method being analyzed .withMessageContaining(" noSuchProperty ") // the property we are looking for .withMessageContaining("UserRepository"); // the repository @@ -231,7 +231,7 @@ public class PartTreeJpaQueryIntegrationTests { JpaQueryMethod queryMethod = getQueryMethod(methodName, parameterTypes); PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager, - PersistenceProvider.fromEntityManager(entityManager), EscapeCharacter.DEFAULT); + PersistenceProvider.fromEntityManager(entityManager)); jpaQuery.createQuery(values); }