diff --git a/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java b/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java index 90b2fe3aa..89bd0b623 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java @@ -52,9 +52,11 @@ public interface CrudMethodMetadata { Map getQueryHints(); /** - * Returns all query hints to be applied to count queries executed for the CRUD method. + * Returns all query hints to be applied to count queries executed for the CRUD method. The default implementation + * just delegates to {@link #getQueryHints()}. * - * The default implementation just delegates to {@link #getQueryHints()}. + * @return + * @since 2.2 */ default Map getQueryHintsForCount() { return getQueryHints(); diff --git a/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java b/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java index 27a30e26c..b8c2813e9 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java @@ -22,12 +22,14 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Predicate; import javax.persistence.LockModeType; import javax.persistence.QueryHint; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; + import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; @@ -165,8 +167,8 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B Assert.notNull(method, "Method must not be null!"); this.lockModeType = findLockModeType(method); - this.queryHints = findQueryHints(method, false); - this.getQueryHintsForCount = findQueryHints(method, true); + this.queryHints = findQueryHints(method, it -> true); + this.getQueryHintsForCount = findQueryHints(method, QueryHints::forCounting); this.entityGraph = findEntityGraph(method); this.method = method; } @@ -182,14 +184,12 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B return annotation == null ? null : (LockModeType) AnnotationUtils.getValue(annotation); } - private static Map findQueryHints(Method method, boolean forCount) { + private static Map findQueryHints(Method method, Predicate annotationFilter) { Map queryHints = new HashMap(); QueryHints queryHintsAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, QueryHints.class); - if (queryHintsAnnotation != null - && (!forCount || queryHintsAnnotation.forCounting()) - ) { + if (queryHintsAnnotation != null && annotationFilter.test(queryHintsAnnotation)) { for (QueryHint hint : queryHintsAnnotation.value()) { queryHints.put(hint.name(), hint.value()); diff --git a/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java b/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java index acf158626..4bfa27de6 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java @@ -1,3 +1,18 @@ +/* + * Copyright 2017-2019 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.support; import java.util.Collections; @@ -40,7 +55,7 @@ class DefaultQueryHints implements QueryHints { * @param forCounts */ private DefaultQueryHints(JpaEntityInformation information, CrudMethodMetadata metadata, - Optional entityManager, boolean forCounts) { + Optional entityManager, boolean forCounts) { this.information = information; this.metadata = metadata; @@ -70,12 +85,16 @@ class DefaultQueryHints implements QueryHints { */ @Override public QueryHints withFetchGraphs(EntityManager em) { - return new DefaultQueryHints(this.information, this.metadata, Optional.of(em), forCounts); + return new DefaultQueryHints(this.information, this.metadata, Optional.of(em), this.forCounts); } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.support.QueryHints#forCounts() + */ @Override public QueryHints forCounts() { - return new DefaultQueryHints(this.information, this.metadata, entityManager, true); + return new DefaultQueryHints(this.information, this.metadata, this.entityManager, true); } /* diff --git a/src/main/java/org/springframework/data/jpa/repository/support/QueryHints.java b/src/main/java/org/springframework/data/jpa/repository/support/QueryHints.java index 9e542aba8..1f41d8267 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/QueryHints.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/QueryHints.java @@ -1,3 +1,18 @@ +/* + * Copyright 2017-2019 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.support; import java.util.Collections; @@ -13,6 +28,7 @@ import javax.persistence.EntityManager; * * @author Christoph Strobl * @author Oliver Gierke + * @author Jens Schauder * @since 2.0 */ interface QueryHints extends Iterable> { @@ -25,11 +41,12 @@ interface QueryHints extends Iterable> { */ QueryHints withFetchGraphs(EntityManager em); - /** - * Creates and returns a new {@link QueryHints} instance that will contain only those hints applicable for count queries. + * Creates and returns a new {@link QueryHints} instance that will contain only those hints applicable for count + * queries. * * @return new instance of {@link QueryHints}. + * @since 2.2 */ QueryHints forCounts(); @@ -50,7 +67,7 @@ interface QueryHints extends Iterable> { INSTANCE; - /* + /* * (non-Javadoc) * @see org.springframework.data.jpa.repository.support.QueryHints#asMap() */ @@ -59,7 +76,7 @@ interface QueryHints extends Iterable> { return Collections.emptyMap(); } - /* + /* * (non-Javadoc) * @see java.lang.Iterable#iterator() */ @@ -68,7 +85,7 @@ interface QueryHints extends Iterable> { return Collections.emptyIterator(); } - /* + /* * (non-Javadoc) * @see org.springframework.data.jpa.repository.support.QueryHints#withFetchGraphs(javax.persistence.EntityManager) */ diff --git a/src/test/java/org/springframework/data/jpa/repository/support/DefaultQueryHintsTest.java b/src/test/java/org/springframework/data/jpa/repository/support/DefaultQueryHintsTest.java index 956e88a25..4d75950ce 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/DefaultQueryHintsTest.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/DefaultQueryHintsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2019 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. @@ -34,6 +34,13 @@ public class DefaultQueryHintsTest { JpaEntityInformation information = mock(JpaEntityInformation.class); CrudMethodMetadata metadata = mock(CrudMethodMetadata.class); + @Before + public void before() { + + setupMainHints(); + setUpCountHints(); + } + @Test // DATAJPA-1156 public void mainHints() { @@ -54,26 +61,21 @@ public class DefaultQueryHintsTest { .containsExactly(null, null, "1", "2"); } - - @Before - public void before() { - - setupMainHints(); - setUpCountHints(); - } - private void setupMainHints() { + Map mainHintMap = new HashMap<>(); mainHintMap.put("name1", "value1"); mainHintMap.put("name2", "value2"); + when(metadata.getQueryHints()).thenReturn(mainHintMap); } private void setUpCountHints() { + Map countHintMap = new HashMap<>(); countHintMap.put("n1", "1"); countHintMap.put("n2", "2"); + when(metadata.getQueryHintsForCount()).thenReturn(countHintMap); } - }