diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java index 2f8ac7639..875f5547b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java @@ -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() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryMethodUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryMethodUnitTests.java index c0517eafb..85b3d47fd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryMethodUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryMethodUnitTests.java @@ -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 { + + @Aggregation("[{'$group': { _id: '$templateId', maxVersion : { $max : '$version'} } }]") + List findByAggregation(); + } + interface Customer { }