Skip to content

Commit dd84d09

Browse files
committed
Reject missing explicitly named queries.
Explicitly configured named queries must either be present in the configured NamedQueries or resolvable through the EntityManager. Previously, a missing @query(name = …) declaration could fall back to query derivation and expose a misleading parameter binding error. Closes #1731 Signed-off-by: 014-code <2402143478@qq.com>
1 parent 517d755 commit dd84d09

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,15 @@ protected RepositoryQuery resolveQuery(JpaQueryMethod method, JpaQueryConfigurat
171171

172172
RepositoryQuery query = NamedQuery.lookupFrom(method, em, configuration);
173173

174-
return query != null ? query : NO_QUERY;
174+
if (query != null) {
175+
return query;
176+
}
177+
178+
if (method.hasAnnotatedQueryName()) {
179+
throw QueryCreationException.create(method, String.format("Did not find named query '%s'", name));
180+
}
181+
182+
return NO_QUERY;
175183
}
176184

177185
private @Nullable DeclaredQuery getCountQuery(JpaQueryMethod method, NamedQueries namedQueries, EntityManager em) {

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategyUnitTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ void prefersDeclaredQuery() throws Exception {
153153
assertThat(repositoryQuery).isInstanceOf(AbstractStringBasedJpaQuery.class);
154154
}
155155

156+
@Test // DATAJPA-1417
157+
void rejectsMissingExplicitNamedQuery() throws Exception {
158+
159+
QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, queryMethodFactory, Key.CREATE_IF_NOT_FOUND,
160+
CONFIG);
161+
Method method = UserRepository.class.getMethod("annotatedQueryNameOnly", String.class, String.class, String.class);
162+
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);
163+
164+
when(em.createNamedQuery("missing-query")).thenThrow(new IllegalArgumentException());
165+
166+
assertThatExceptionOfType(QueryCreationException.class)
167+
.isThrownBy(() -> strategy.resolveQuery(method, metadata, projectionFactory, namedQueries))
168+
.withMessageContaining("Did not find named query 'missing-query'");
169+
}
170+
156171
@Test // GH-2018
157172
void namedQueryWithSortShouldThrowIllegalStateException() throws NoSuchMethodException {
158173

@@ -228,6 +243,9 @@ interface UserRepository extends Repository<User, Integer> {
228243
@Query(value = "select foo from Foo foo", name = "my-query-name")
229244
User annotatedQueryWithQueryAndQueryName();
230245

246+
@Query(name = "missing-query")
247+
List<User> annotatedQueryNameOnly(String firstname, String lastname, String emailAddress);
248+
231249
@Query("SELECT * FROM table WHERE (json_col->'jsonKey')::jsonb \\?\\? :param ")
232250
List<User> customQueryWithQuestionMarksAndNamedParam(String param);
233251

0 commit comments

Comments
 (0)