diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index bdaf66dce..8cc0144c9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -1918,7 +1918,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, if (query.getLimit() > 0 && mapReduceOptions != null && mapReduceOptions.getLimit() == null) { mapReduce = mapReduce.limit(query.getLimit()); } - if (query.getMeta().getMaxTimeMsec() != null) { + if (query.getMeta().hasMaxTime()) { mapReduce = mapReduce.maxTime(query.getMeta().getMaxTimeMsec(), TimeUnit.MILLISECONDS); } @@ -3411,12 +3411,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, if (meta.hasValues()) { - if (StringUtils.hasText(meta.getComment())) { - cursorToUse = cursorToUse.comment(meta.getComment()); + if (meta.hasComment()) { + cursorToUse = cursorToUse.comment(meta.getRequiredComment()); } - if (meta.getMaxTimeMsec() != null) { - cursorToUse = cursorToUse.maxTime(meta.getMaxTimeMsec(), TimeUnit.MILLISECONDS); + if (meta.hasMaxTime()) { + cursorToUse = cursorToUse.maxTime(meta.getRequiredMaxTimeMsec(), TimeUnit.MILLISECONDS); } if (meta.getCursorBatchSize() != null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java index c3acbd994..36876e18f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java @@ -53,6 +53,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.ShardKey; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.data.mongodb.core.query.Meta; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.mongodb.core.query.UpdateDefinition.ArrayFilter; @@ -67,7 +68,6 @@ import com.mongodb.client.model.CountOptions; import com.mongodb.client.model.DeleteOptions; import com.mongodb.client.model.ReplaceOptions; import com.mongodb.client.model.UpdateOptions; -import org.springframework.util.StringUtils; /** * {@link QueryOperations} centralizes common operations required before an operation is actually ready to be executed. @@ -390,7 +390,7 @@ class QueryOperations { for (Entry entry : fields.entrySet()) { - if (entry.getValue() instanceof MongoExpression) { + if (entry.getValue()instanceof MongoExpression) { AggregationOperationContext ctx = entity == null ? Aggregation.DEFAULT_CONTEXT : new RelaxedTypeBasedAggregationOperationContext(entity.getType(), mappingContext, queryMapper); @@ -566,16 +566,20 @@ class QueryOperations { if (query.getLimit() > 0) { options.limit(query.getLimit()); } + if (query.getSkip() > 0) { options.skip((int) query.getSkip()); } - if(query.getMeta().hasValues()) { - if(query.getMeta().getMaxTimeMsec() != null && query.getMeta().getMaxTimeMsec() > 0) { - options.maxTime(query.getMeta().getMaxTimeMsec(), TimeUnit.MILLISECONDS); + Meta meta = query.getMeta(); + if (meta.hasValues()) { + + if (meta.hasMaxTime()) { + options.maxTime(meta.getRequiredMaxTimeMsec(), TimeUnit.MILLISECONDS); } - if(StringUtils.hasText(query.getMeta().getComment())) { - options.comment(query.getMeta().getComment()); + + if (meta.hasComment()) { + options.comment(meta.getComment()); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 45da65a16..46372015d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -2305,8 +2305,9 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati publisher.sort(mappedSort); } - if (filterQuery.getMeta().getMaxTimeMsec() != null) { - publisher.maxTime(filterQuery.getMeta().getMaxTimeMsec(), TimeUnit.MILLISECONDS); + Meta meta = filterQuery.getMeta(); + if (meta.hasMaxTime()) { + publisher.maxTime(meta.getRequiredMaxTimeMsec(), TimeUnit.MILLISECONDS); } if (filterQuery.getLimit() > 0 || (options.getLimit() != null)) { @@ -3454,12 +3455,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati if (meta.hasValues()) { - if (StringUtils.hasText(meta.getComment())) { - findPublisherToUse = findPublisherToUse.comment(meta.getComment()); + if (meta.hasComment()) { + findPublisherToUse = findPublisherToUse.comment(meta.getRequiredComment()); } - if (meta.getMaxTimeMsec() != null) { - findPublisherToUse = findPublisherToUse.maxTime(meta.getMaxTimeMsec(), TimeUnit.MILLISECONDS); + if (meta.hasMaxTime()) { + findPublisherToUse = findPublisherToUse.maxTime(meta.getRequiredMaxTimeMsec(), TimeUnit.MILLISECONDS); } if (meta.getCursorBatchSize() != null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java index 64ceb0820..9e42abd7b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java @@ -70,6 +70,19 @@ public class Meta { this.allowDiskUse = source.allowDiskUse; } + /** + * Return whether the maximum time limit for processing operations is set. + * + * @return {@code true} if set; {@code false} otherwise. + * @since 3.4.12 + */ + public boolean hasMaxTime() { + + Long maxTimeMsec = getMaxTimeMsec(); + + return maxTimeMsec != null && maxTimeMsec > 0; + } + /** * @return {@literal null} if not set. */ @@ -78,6 +91,26 @@ public class Meta { return getValue(MetaKey.MAX_TIME_MS.key); } + /** + * Returns the required maximum time limit in milliseconds or throws {@link IllegalStateException} if the maximum time + * limit is not set. + * + * @return the maximum time limit in milliseconds for processing operations. + * @throws IllegalStateException if the maximum time limit is not set + * @see #hasMaxTime() + * @since 3.4.12 + */ + public Long getRequiredMaxTimeMsec() { + + Long maxTimeMsec = getMaxTimeMsec(); + + if (maxTimeMsec == null) { + throw new IllegalStateException("Maximum time limit in milliseconds not set"); + } + + return maxTimeMsec; + } + /** * Set the maximum time limit in milliseconds for processing operations. * @@ -112,12 +145,13 @@ public class Meta { } /** - * Add a comment to the query that is propagated to the profile log. + * Return whether the comment is set. * - * @param comment + * @return {@code true} if set; {@code false} otherwise. + * @since 3.4.12 */ - public void setComment(String comment) { - setValue(MetaKey.COMMENT.key, comment); + public boolean hasComment() { + return StringUtils.hasText(getComment()); } /** @@ -128,6 +162,34 @@ public class Meta { return getValue(MetaKey.COMMENT.key); } + /** + * Returns the required comment or throws {@link IllegalStateException} if the comment is not set. + * + * @return the comment. + * @throws IllegalStateException if the comment is not set + * @see #hasComment() + * @since 3.4.12 + */ + public String getRequiredComment() { + + String comment = getComment(); + + if (comment == null) { + throw new IllegalStateException("Comment not set"); + } + + return comment; + } + + /** + * Add a comment to the query that is propagated to the profile log. + * + * @param comment + */ + public void setComment(String comment) { + setValue(MetaKey.COMMENT.key, comment); + } + /** * @return {@literal null} if not set. * @since 2.1 diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java index 0ee488c33..b720aae05 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java @@ -36,7 +36,6 @@ import org.springframework.expression.ExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; /** * Internal utility class to help avoid duplicate code required in both the reactive and the sync {@link Aggregation} @@ -83,7 +82,7 @@ abstract class AggregationUtils { Meta meta = queryMethod.getQueryMetaAttributes(); - if (StringUtils.hasText(meta.getComment())) { + if (meta.hasComment()) { builder.comment(meta.getComment()); } @@ -91,8 +90,8 @@ abstract class AggregationUtils { builder.cursorBatchSize(meta.getCursorBatchSize()); } - if (meta.getMaxTimeMsec() != null && meta.getMaxTimeMsec() > 0) { - builder.maxTime(Duration.ofMillis(meta.getMaxTimeMsec())); + if (meta.hasMaxTime()) { + builder.maxTime(Duration.ofMillis(meta.getRequiredMaxTimeMsec())); } if (meta.getAllowDiskUse() != null) { 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 70e6a0179..184c165ea 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 @@ -272,7 +272,8 @@ public class MongoQueryMethodUnitTests { void queryCreationForUpdateMethodFailsOnInvalidReturnType() throws Exception { assertThatExceptionOfType(IllegalStateException.class) // - .isThrownBy(() -> queryMethod(InvalidUpdateMethodRepo.class, "findAndIncrementVisitsByFirstname", String.class).verify()) // + .isThrownBy(() -> queryMethod(InvalidUpdateMethodRepo.class, "findAndIncrementVisitsByFirstname", String.class) + .verify()) // .withMessageContaining("Update") // .withMessageContaining("numeric") // .withMessageContaining("findAndIncrementVisitsByFirstname");