Browse Source

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 #1061.
2.2.x
Mark Paluch 4 years ago
parent
commit
56ad839867
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 10
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java
  2. 3
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java
  3. 10
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java
  4. 17
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java

10
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java

@ -151,6 +151,15 @@ public class JdbcQueryMethod extends QueryMethod {
return this.namedQueries.hasQuery(name) ? this.namedQueries.getQuery(name) : null; return this.namedQueries.hasQuery(name) ? this.namedQueries.getQuery(name) : null;
} }
/**
* @return {@literal true} if the method is annotated with {@code @Query(name=)}.
*/
public boolean hasAnnotatedQueryName() {
return lookupQueryAnnotation() //
.map(Query::name) //
.map(StringUtils::hasText).orElse(false);
}
@Override @Override
public String getNamedQueryName() { public String getNamedQueryName() {
@ -159,6 +168,7 @@ public class JdbcQueryMethod extends QueryMethod {
return StringUtils.hasText(annotatedName) ? annotatedName : super.getNamedQueryName(); return StringUtils.hasText(annotatedName) ? annotatedName : super.getNamedQueryName();
} }
/** /**
* Returns the class to be used as {@link org.springframework.jdbc.core.RowMapper} * Returns the class to be used as {@link org.springframework.jdbc.core.RowMapper}
* *

3
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java

@ -34,6 +34,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -143,7 +144,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
String query = queryMethod.getDeclaredQuery(); String query = queryMethod.getDeclaredQuery();
if (StringUtils.isEmpty(query)) { if (ObjectUtils.isEmpty(query)) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName())); throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
} }

10
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java

@ -19,6 +19,9 @@ import java.lang.reflect.Method;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.jdbc.core.convert.EntityRowMapper; import org.springframework.data.jdbc.core.convert.EntityRowMapper;
@ -58,6 +61,8 @@ import org.springframework.util.Assert;
*/ */
class JdbcQueryLookupStrategy implements QueryLookupStrategy { class JdbcQueryLookupStrategy implements QueryLookupStrategy {
private static final Log LOG = LogFactory.getLog(JdbcQueryLookupStrategy.class);
private final ApplicationEventPublisher publisher; private final ApplicationEventPublisher publisher;
private final @Nullable EntityCallbacks callbacks; private final @Nullable EntityCallbacks callbacks;
private final RelationalMappingContext context; private final RelationalMappingContext context;
@ -103,6 +108,11 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
try { try {
if (namedQueries.hasQuery(queryMethod.getNamedQueryName()) || queryMethod.hasAnnotatedQuery()) { if (namedQueries.hasQuery(queryMethod.getNamedQueryName()) || queryMethod.hasAnnotatedQuery()) {
if (queryMethod.hasAnnotatedQuery() && queryMethod.hasAnnotatedQueryName()) {
LOG.warn(String.format(
"Query method %s is annotated with both, a query and a query name. Using the declared query.", method));
}
RowMapper<?> mapper = queryMethod.isModifyingQuery() ? null : createMapper(queryMethod); RowMapper<?> mapper = queryMethod.isModifyingQuery() ? null : createMapper(queryMethod);
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, mapper, converter); StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, mapper, converter);
query.setBeanFactory(beanfactory); query.setBeanFactory(beanfactory);

17
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java

@ -88,6 +88,20 @@ public class JdbcQueryLookupStrategyUnitTests {
verify(operations).queryForObject(anyString(), any(SqlParameterSource.class), any(RowMapper.class)); verify(operations).queryForObject(anyString(), any(SqlParameterSource.class), any(RowMapper.class));
} }
@Test // GH-1061
public void prefersDeclaredQuery() {
RowMapper<? extends NumberFormat> numberFormatMapper = mock(RowMapper.class);
QueryMappingConfiguration mappingConfiguration = new DefaultQueryMappingConfiguration()
.registerRowMapper(NumberFormat.class, numberFormatMapper);
RepositoryQuery repositoryQuery = getRepositoryQuery("annotatedQueryWithQueryAndQueryName", mappingConfiguration);
repositoryQuery.execute(new Object[] {});
verify(operations).queryForObject(eq("some SQL"), any(SqlParameterSource.class), any(RowMapper.class));
}
private RepositoryQuery getRepositoryQuery(String name, QueryMappingConfiguration mappingConfiguration) { private RepositoryQuery getRepositoryQuery(String name, QueryMappingConfiguration mappingConfiguration) {
JdbcQueryLookupStrategy queryLookupStrategy = new JdbcQueryLookupStrategy(publisher, callbacks, mappingContext, JdbcQueryLookupStrategy queryLookupStrategy = new JdbcQueryLookupStrategy(publisher, callbacks, mappingContext,
@ -102,5 +116,8 @@ public class JdbcQueryLookupStrategyUnitTests {
// NumberFormat is just used as an arbitrary non simple type. // NumberFormat is just used as an arbitrary non simple type.
@Query("some SQL") @Query("some SQL")
NumberFormat returningNumberFormat(); NumberFormat returningNumberFormat();
@Query(value = "some SQL", name = "query-name")
void annotatedQueryWithQueryAndQueryName();
} }
} }

Loading…
Cancel
Save