Validate aggregation query method on query method creation.

This commit makes sure to fail early if an annotated string based annotation does not contain a syntactically valid pipeline.

Original pull request: #4547
Closes #4546
This commit is contained in:
Christoph Strobl
2023-11-03 13:55:06 +01:00
committed by Mark Paluch
parent bc18b5291d
commit 512f81fa96
2 changed files with 26 additions and 0 deletions

View File

@@ -38,6 +38,7 @@ import org.springframework.data.mongodb.repository.Meta;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.Tailable;
import org.springframework.data.mongodb.repository.Update;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
@@ -456,6 +457,16 @@ public class MongoQueryMethod extends QueryMethod {
}
}
}
if (hasAnnotatedAggregation()) {
for (String stage : getAnnotatedAggregation()) {
if (BsonUtils.isJsonArray(stage)) {
throw new IllegalStateException("""
Invalid aggregation pipeline. Please split Aggregation.pipeline from "[{...}, {...}]" to "{...}", "{...}".
Offending Method: %s.%s
""".formatted(method.getDeclaringClass().getSimpleName(), method.getName()));
}
}
}
}
private boolean isNumericOrVoidReturnValue() {

View File

@@ -311,6 +311,15 @@ public class MongoQueryMethodUnitTests {
assertThat(method.getAnnotatedCollation()).isEqualTo("de_AT");
}
@Test // GH-4546
void errorsOnInvalidAggregation() throws Exception {
assertThatExceptionOfType(IllegalStateException.class) //
.isThrownBy(() -> queryMethod(InvalidAggregationMethodRepo.class, "findByAggregation").verify()) //
.withMessageContaining("Invalid aggregation") //
.withMessageContaining("findByAggregation");
}
private MongoQueryMethod queryMethod(Class<?> repository, String name, Class<?>... parameters) throws Exception {
Method method = repository.getMethod(name, parameters);
@@ -404,6 +413,12 @@ public class MongoQueryMethodUnitTests {
Person findAndIncrementVisitsByFirstname(String firstname);
}
interface InvalidAggregationMethodRepo extends Repository<Person, Long> {
@Aggregation("[{'$group': { _id: '$templateId', maxVersion : { $max : '$version'} } }]")
List<User> findByAggregation();
}
interface Customer {
}