mirror of
https://github.com/spring-projects/spring-data-jpa.git
synced 2026-05-04 05:19:49 +01:00
Improve query method validation exceptions for declared queries.
When validating manually declared queries on repositories, the exception that captures the query to validate now actually also reports it in the exception message. Closes: #2736. Original pull request: #2738
This commit is contained in:
committed by
Mark Paluch
parent
05dfa2b805
commit
d854c63f12
+14
-14
@@ -40,13 +40,13 @@ final class SimpleJpaQuery extends AbstractStringBasedJpaQuery {
|
|||||||
*
|
*
|
||||||
* @param method must not be {@literal null}
|
* @param method must not be {@literal null}
|
||||||
* @param em must not be {@literal null}
|
* @param em must not be {@literal null}
|
||||||
* @param countQueryString
|
* @param sourceQuery the original source query, must not be {@literal null} or empty.
|
||||||
* @param queryRewriter must not be {@literal null}
|
* @param queryRewriter must not be {@literal null}
|
||||||
* @param valueExpressionDelegate must not be {@literal null}
|
* @param valueExpressionDelegate must not be {@literal null}
|
||||||
*/
|
*/
|
||||||
public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, @Nullable String countQueryString,
|
public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, @Nullable String sourceQuery,
|
||||||
QueryRewriter queryRewriter, ValueExpressionDelegate valueExpressionDelegate) {
|
QueryRewriter queryRewriter, ValueExpressionDelegate valueExpressionDelegate) {
|
||||||
this(method, em, method.getRequiredAnnotatedQuery(), countQueryString, queryRewriter, valueExpressionDelegate);
|
this(method, em, method.getRequiredAnnotatedQuery(), sourceQuery, queryRewriter, valueExpressionDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,21 +54,20 @@ final class SimpleJpaQuery extends AbstractStringBasedJpaQuery {
|
|||||||
*
|
*
|
||||||
* @param method must not be {@literal null}
|
* @param method must not be {@literal null}
|
||||||
* @param em must not be {@literal null}
|
* @param em must not be {@literal null}
|
||||||
* @param queryString must not be {@literal null} or empty
|
* @param sourceQuery the original source query, must not be {@literal null} or empty
|
||||||
* @param countQueryString
|
* @param countQueryString
|
||||||
* @param queryRewriter
|
* @param queryRewriter
|
||||||
* @param valueExpressionDelegate must not be {@literal null}
|
* @param valueExpressionDelegate must not be {@literal null}
|
||||||
*/
|
*/
|
||||||
public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, String queryString, @Nullable String countQueryString, QueryRewriter queryRewriter,
|
public SimpleJpaQuery(JpaQueryMethod method, EntityManager em, String sourceQuery, @Nullable String countQueryString,
|
||||||
ValueExpressionDelegate valueExpressionDelegate) {
|
QueryRewriter queryRewriter, ValueExpressionDelegate valueExpressionDelegate) {
|
||||||
|
|
||||||
super(method, em, queryString, countQueryString, queryRewriter, valueExpressionDelegate);
|
super(method, em, sourceQuery, countQueryString, queryRewriter, valueExpressionDelegate);
|
||||||
|
|
||||||
validateQuery(getQuery().getQueryString(), "Validation failed for query for method %s", method);
|
validateQuery(getQuery(), "Validation failed for query %s for method %s", method);
|
||||||
|
|
||||||
if (method.isPageQuery()) {
|
if (method.isPageQuery()) {
|
||||||
validateQuery(getCountQuery().getQueryString(),
|
validateQuery(getCountQuery(), "Count query %s validation failed for method %s", method);
|
||||||
String.format("Count query validation failed for method %s", method));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,23 +77,24 @@ final class SimpleJpaQuery extends AbstractStringBasedJpaQuery {
|
|||||||
* @param query
|
* @param query
|
||||||
* @param errorMessage
|
* @param errorMessage
|
||||||
*/
|
*/
|
||||||
private void validateQuery(String query, String errorMessage, Object... arguments) {
|
private void validateQuery(DeclaredQuery query, String errorMessage, JpaQueryMethod method) {
|
||||||
|
|
||||||
if (getQueryMethod().isProcedureQuery()) {
|
if (getQueryMethod().isProcedureQuery()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityManager validatingEm = null;
|
EntityManager validatingEm = null;
|
||||||
|
var queryString = query.getQueryString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager();
|
validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager();
|
||||||
validatingEm.createQuery(query);
|
validatingEm.createQuery(queryString);
|
||||||
|
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
|
|
||||||
// Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider
|
// Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider
|
||||||
// https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17
|
// https://download.oracle.com/javaee-archive/jpa-spec.java.net/users/2012/07/0404.html
|
||||||
throw new IllegalArgumentException(String.format(errorMessage, arguments), e);
|
throw new IllegalArgumentException(errorMessage.formatted(query, method), e);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -40,7 +40,6 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.mockito.junit.jupiter.MockitoSettings;
|
import org.mockito.junit.jupiter.MockitoSettings;
|
||||||
import org.mockito.quality.Strictness;
|
import org.mockito.quality.Strictness;
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -194,14 +193,15 @@ class SimpleJpaQueryUnitTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAJPA-352
|
@Test // DATAJPA-352
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
void validatesAndRejectsCountQueryIfPagingMethod() throws Exception {
|
void validatesAndRejectsCountQueryIfPagingMethod() throws Exception {
|
||||||
|
|
||||||
Method method = SampleRepository.class.getMethod("pageByAnnotatedQuery", Pageable.class);
|
Method method = SampleRepository.class.getMethod("pageByAnnotatedQuery", Pageable.class);
|
||||||
|
|
||||||
when(em.createQuery(Mockito.contains("count"))).thenThrow(IllegalArgumentException.class);
|
when(em.createQuery(Mockito.contains("count"))).thenThrow(IllegalArgumentException.class);
|
||||||
|
|
||||||
assertThatIllegalArgumentException().isThrownBy(() -> createJpaQuery(method)).withMessageContaining("Count")
|
assertThatIllegalArgumentException() //
|
||||||
|
.isThrownBy(() -> createJpaQuery(method)) //
|
||||||
|
.withMessageContaining("Count") //
|
||||||
.withMessageContaining(method.getName());
|
.withMessageContaining(method.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user