Log a warning when a query method is annotated with a query and a query name.
We now log when a query method has an ambiguous declaration to clarify that the declared query is used. Closes #2319
This commit is contained in:
@@ -19,6 +19,9 @@ import java.lang.reflect.Method;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
@@ -40,6 +43,8 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public final class JpaQueryLookupStrategy {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JpaQueryLookupStrategy.class);
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
@@ -145,6 +150,11 @@ public final class JpaQueryLookupStrategy {
|
||||
|
||||
RepositoryQuery query = JpaQueryFactory.INSTANCE.fromQueryAnnotation(method, em, evaluationContextProvider);
|
||||
|
||||
if (query != null && method.hasAnnotatedQueryName()) {
|
||||
LOG.warn(String.format(
|
||||
"Query method %s is annotated with both, a query and a query name. Using the declared query.", method));
|
||||
}
|
||||
|
||||
if (null != query) {
|
||||
return query;
|
||||
}
|
||||
|
||||
@@ -274,6 +274,13 @@ public class JpaQueryMethod extends QueryMethod {
|
||||
return StringUtils.hasText(query) ? query : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if this method is annotated with {@code @Query(name=…)}.
|
||||
*/
|
||||
boolean hasAnnotatedQueryName() {
|
||||
return StringUtils.hasText(getAnnotationValue("name", String.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the required query string declared in a {@link Query} annotation or throws {@link IllegalStateException} if
|
||||
* neither the annotation found nor the attribute was specified.
|
||||
@@ -442,4 +449,5 @@ public class JpaQueryMethod extends QueryMethod {
|
||||
|
||||
return storedProcedureAttributes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JpaQueryLookupStrategy}.
|
||||
@@ -110,6 +111,19 @@ public class JpaQueryLookupStrategyUnitTests {
|
||||
.withMessageContaining(method.toString());
|
||||
}
|
||||
|
||||
@Test // GH-2319
|
||||
void prefersDeclaredQuery() throws Exception {
|
||||
|
||||
QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, queryMethodFactory, Key.CREATE_IF_NOT_FOUND,
|
||||
EVALUATION_CONTEXT_PROVIDER, EscapeCharacter.DEFAULT);
|
||||
Method method = UserRepository.class.getMethod("annotatedQueryWithQueryAndQueryName");
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);
|
||||
|
||||
RepositoryQuery repositoryQuery = strategy.resolveQuery(method, metadata, projectionFactory, namedQueries);
|
||||
|
||||
assertThat(repositoryQuery).isInstanceOf(AbstractStringBasedJpaQuery.class);
|
||||
}
|
||||
|
||||
interface UserRepository extends Repository<User, Integer> {
|
||||
|
||||
@Query("something absurd")
|
||||
@@ -117,5 +131,8 @@ public class JpaQueryLookupStrategyUnitTests {
|
||||
|
||||
@Query(value = "select u.* from User u", nativeQuery = true)
|
||||
List<User> findByInvalidNativeQuery(String param, Sort sort);
|
||||
|
||||
@Query(value = "something absurd", name = "my-query-name")
|
||||
User annotatedQueryWithQueryAndQueryName();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user