diff --git a/src/docbkx/reference/jpa.xml b/src/docbkx/reference/jpa.xml
index c72e30edf..9a29f5c4e 100644
--- a/src/docbkx/reference/jpa.xml
+++ b/src/docbkx/reference/jpa.xml
@@ -18,8 +18,8 @@
The JPA module of Spring Data contains a custom namespace that
allows defining repository beans. It also contains certain features and
element attributes that are special to JPA. Generally the JPA
- repositories can be set up using the repositories element:
-
+ repositories can be set up using the repositories
+ element:
Setting up JPA repositories using the namespace
@@ -444,6 +444,33 @@ int setFixedFirstnameFor(String firstname, String lastname);
clearAutomatically attribute to
false;
+
+
+ Applying query hints
+
+ To apply JPA QueryHints to the
+ queries declared in your repository interface you can use the
+ QueryHints annotation. It takes an array
+ of JPA QueryHint annotations plus a
+ boolean flag to potentially disable the hints applied to the addtional
+ count query triggered when applying pagination.
+
+
+ Using QueryHints with a repository method
+
+ public interface UserRepository extends Repository<User, Long> {
+
+ @QueryHints(value = { @QueryHint(name = "name", value = "value")},
+ forCounting = false)
+ Page<User> findByLastname(String lastname, Pageable pageable);
+}
+
+ The just shown declaration would apply the configured
+ QueryHint for that actually query but
+ omit applying it to the count query triggered to calculate the total
+ number of pages.
+
+
diff --git a/src/main/java/org/springframework/data/jpa/repository/QueryHints.java b/src/main/java/org/springframework/data/jpa/repository/QueryHints.java
index d375cab4c..750a72aaa 100644
--- a/src/main/java/org/springframework/data/jpa/repository/QueryHints.java
+++ b/src/main/java/org/springframework/data/jpa/repository/QueryHints.java
@@ -34,5 +34,18 @@ import javax.persistence.QueryHint;
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryHints {
+ /**
+ * The {@link QueryHint}s to apply when the query will be executed.
+ *
+ * @return
+ */
QueryHint[] value() default {};
+
+ /**
+ * Defines whether the configured {@link QueryHint}s shall be applied for count queries during pagination as well.
+ * Defaults to {@literal true}.
+ *
+ * @return
+ */
+ boolean forCounting() default true;
}
diff --git a/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java
index 8b124a1f4..99bea4a8a 100644
--- a/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java
+++ b/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java
@@ -131,7 +131,8 @@ public abstract class AbstractJpaQuery implements RepositoryQuery {
}
protected TypedQuery createCountQuery(Object[] values) {
- return applyHints(doCreateCountQuery(values), method);
+ TypedQuery countQuery = doCreateCountQuery(values);
+ return method.applyHintsToCountQuery() ? applyHints(countQuery, method) : countQuery;
}
/**
diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java
index 96679008e..811665cd3 100644
--- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java
+++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java
@@ -93,6 +93,18 @@ public class JpaQueryMethod extends QueryMethod {
return result;
}
+ /**
+ * Returns whether the potentially configured {@link QueryHint}s shall be applied when triggering the count query for
+ * pagination.
+ *
+ * @return
+ */
+ boolean applyHintsToCountQuery() {
+
+ QueryHints hints = getAnnotation(method, QueryHints.class);
+ return hints != null ? hints.forCounting() : false;
+ }
+
/**
* Returns the {@link QueryExtractor}.
*
diff --git a/src/test/java/org/springframework/data/jpa/repository/query/AbstractJpaQueryTests.java b/src/test/java/org/springframework/data/jpa/repository/query/AbstractJpaQueryTests.java
index b79dcb246..e1f61397c 100644
--- a/src/test/java/org/springframework/data/jpa/repository/query/AbstractJpaQueryTests.java
+++ b/src/test/java/org/springframework/data/jpa/repository/query/AbstractJpaQueryTests.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2008-2011 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.query;
import static org.mockito.Mockito.*;
@@ -65,10 +80,34 @@ public class AbstractJpaQueryTests {
verify(result).setHint("foo", "bar");
}
+ /**
+ * @see DATAJPA-54
+ * @throws Exception
+ */
+ @Test
+ public void skipsHintsForCountQueryIfConfigured() throws Exception {
+
+ Method method = SampleRepository.class.getMethod("findByFirstname", String.class);
+ QueryExtractor provider = PersistenceProvider.fromEntityManager(em);
+ JpaQueryMethod queryMethod = new JpaQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class),
+ provider);
+
+ AbstractJpaQuery jpaQuery = new DummyJpaQuery(queryMethod, em);
+
+ Query result = jpaQuery.createQuery(new Object[] { "Dave" });
+ verify(result).setHint("bar", "foo");
+
+ result = jpaQuery.createCountQuery(new Object[] { "Dave" });
+ verify(result, never()).setHint("bar", "foo");
+ }
+
interface SampleRepository extends Repository {
@QueryHints({ @QueryHint(name = "foo", value = "bar") })
List findByLastname(String lastname);
+
+ @QueryHints(value = { @QueryHint(name = "bar", value = "foo") }, forCounting = false)
+ List findByFirstname(String firstname);
}
class DummyJpaQuery extends AbstractJpaQuery {