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 fc3130bfb..6b57a3159 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 @@ -62,14 +62,15 @@ final class SimpleJpaQuery extends AbstractJpaQuery { String preparedQueryString = this.query.getQuery(); if (!method.isNativeQuery()) { - validateQuery(preparedQueryString, em); + validateQuery(preparedQueryString, em, String.format("Validation failed for query for method %s!", method)); } this.countQuery = new StringQuery(method.getCountQuery() != null ? method.getCountQuery() : QueryUtils.createCountQueryFor(preparedQueryString)); - if (!method.isNativeQuery()) { - validateQuery(this.countQuery.getQuery(), em); + if (!method.isNativeQuery() && method.isPageQuery()) { + validateQuery(this.countQuery.getQuery(), em, + String.format("Count query validation failed for method %s!", method)); } } @@ -79,7 +80,7 @@ final class SimpleJpaQuery extends AbstractJpaQuery { * @param query * @param em */ - private final void validateQuery(String query, EntityManager em) { + private final void validateQuery(String query, EntityManager em, String errorMessage) { EntityManager validatingEm = null; @@ -92,7 +93,7 @@ final class SimpleJpaQuery extends AbstractJpaQuery { // Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider // http://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17 - throw e instanceof IllegalArgumentException ? e : new IllegalArgumentException(e); + throw new IllegalArgumentException(errorMessage, e); } finally { 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 96e7e7e36..e4aaed99e 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 @@ -28,11 +28,14 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.TypedQuery; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -50,6 +53,8 @@ import org.springframework.data.repository.query.Parameters; @RunWith(MockitoJUnitRunner.class) public class SimpleJpaQueryUnitTests { + static final String USER_QUERY = "select u from User u"; + JpaQueryMethod method; @Mock EntityManager em; @@ -59,6 +64,8 @@ public class SimpleJpaQueryUnitTests { @Mock RepositoryMetadata metadata; @Mock ParameterBinder binder; + public @Rule ExpectedException exception = ExpectedException.none(); + @Before public void setUp() throws SecurityException, NoSuchMethodException { @@ -124,17 +131,48 @@ public class SimpleJpaQueryUnitTests { public void rejectsNativeQueryWithDynamicSort() throws Exception { Method method = SampleRepository.class.getMethod("findNativeByLastname", String.class, Sort.class); - rejectsNativeQuery(method); + createSimpleJpaQuery(method); } @Test(expected = IllegalStateException.class) public void rejectsNativeQueryWithPageable() throws Exception { Method method = SampleRepository.class.getMethod("findNativeByLastname", String.class, Pageable.class); - rejectsNativeQuery(method); + createSimpleJpaQuery(method); } - private void rejectsNativeQuery(Method method) { + /** + * @see DATAJPA-352 + * @throws Exception + */ + @Test + @SuppressWarnings("unchecked") + public void doesNotValidateCountQueryIfNotPagingMethod() throws Exception { + + Method method = SampleRepository.class.getMethod("findByAnnotatedQuery"); + when(em.createQuery(contains("count"))).thenThrow(IllegalArgumentException.class); + + createSimpleJpaQuery(method); + } + + /** + * @see DATAJPA-352 + */ + @Test + @SuppressWarnings("unchecked") + public void validatesAndRejectsCountQueryIfPagingMethod() throws Exception { + + Method method = SampleRepository.class.getMethod("pageByAnnotatedQuery", Pageable.class); + + when(em.createQuery(contains("count"))).thenThrow(IllegalArgumentException.class); + exception.expect(IllegalArgumentException.class); + exception.expectMessage("Count"); + exception.expectMessage(method.getName()); + + createSimpleJpaQuery(method); + } + + private void createSimpleJpaQuery(Method method) { JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor); new SimpleJpaQuery(queryMethod, em); @@ -150,5 +188,11 @@ public class SimpleJpaQueryUnitTests { @Query(value = "SELECT u FROM User u WHERE u.lastname = ?1", nativeQuery = true) List findNativeByLastname(String lastname, Pageable pageable); + + @Query(USER_QUERY) + List findByAnnotatedQuery(); + + @Query(USER_QUERY) + Page pageByAnnotatedQuery(Pageable pageable); } }