From c37dfd9688ea5de53d56b04b77596b22c9dae599 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 6 Mar 2017 09:03:34 +0100 Subject: [PATCH] DATAMONGO-1421 - Fix serialization in error message causing error itself. We now make sure to safely serialize the criteria object used for creating the error message when raising an `InvalidMongoDbApiUsageException` in cases where `addCriteria` is used to add multiple entries for the same property. Original pull request: #448. --- .../data/mongodb/core/query/Query.java | 32 +++++++++---------- .../data/mongodb/core/query/QueryTests.java | 19 ++++++++++- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java index 8e7811b9b..d2c584370 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ public class Query { /** * Static factory method to create a {@link Query} using the provided {@link CriteriaDefinition}. - * + * * @param criteriaDefinition must not be {@literal null}. * @return * @since 1.6 @@ -70,7 +70,7 @@ public class Query { /** * Creates a new {@link Query} using the given {@link CriteriaDefinition}. - * + * * @param criteriaDefinition must not be {@literal null}. * @since 1.6 */ @@ -80,7 +80,7 @@ public class Query { /** * Adds the given {@link CriteriaDefinition} to the current {@link Query}. - * + * * @param criteriaDefinition must not be {@literal null}. * @return * @since 1.6 @@ -95,7 +95,7 @@ public class Query { } else { throw new InvalidMongoDbApiUsageException( "Due to limitations of the com.mongodb.BasicDocument, " + "you can't add a second '" + key + "' criteria. " - + "Query already contains '" + existing.getCriteriaObject() + "'."); + + "Query already contains '" + serializeToJsonSafely(existing.getCriteriaObject()) + "'."); } return this; @@ -110,7 +110,7 @@ public class Query { /** * Set number of documents to skip before returning results. - * + * * @param skip * @return */ @@ -121,7 +121,7 @@ public class Query { /** * Limit the number of returned documents to {@code limit}. - * + * * @param limit * @return */ @@ -132,7 +132,7 @@ public class Query { /** * Configures the query to use the given hint when being executed. - * + * * @param name must not be {@literal null} or empty. * @return */ @@ -145,7 +145,7 @@ public class Query { /** * Sets the given pagination information on the {@link Query} instance. Will transparently set {@code skip} and * {@code limit} as well as applying the {@link Sort} instance defined with the {@link Pageable}. - * + * * @param pageable * @return */ @@ -163,7 +163,7 @@ public class Query { /** * Adds a {@link Sort} to the {@link Query} instance. - * + * * @param sort * @return */ @@ -198,7 +198,7 @@ public class Query { /** * Restricts the query to only return documents instances that are exactly of the given types. - * + * * @param type may not be {@literal null} * @param additionalTypes may not be {@literal null} * @return @@ -252,7 +252,7 @@ public class Query { /** * Get the number of documents to skip. - * + * * @return */ public int getSkip() { @@ -261,7 +261,7 @@ public class Query { /** * Get the maximum number of documents to be return. - * + * * @return */ public int getLimit() { @@ -431,7 +431,7 @@ public class Query { /** * Tests whether the settings of the given {@link Query} are equal to this query. - * + * * @param that * @return */ @@ -448,7 +448,7 @@ public class Query { return criteriaEqual && fieldsEqual && sortEqual && hintEqual && skipEqual && limitEqual && metaEqual; } - /* + /* * (non-Javadoc) * @see java.lang.Object#hashCode() */ @@ -470,7 +470,7 @@ public class Query { /** * Returns whether the given key is the one used to hold the type restriction information. - * + * * @deprecated don't call this method as the restricted type handling will undergo some significant changes going * forward. * @param key diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java index 238b8e524..f2b736018 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java @@ -34,11 +34,12 @@ import org.springframework.data.mongodb.core.SpecialDoc; /** * Unit tests for {@link Query}. - * + * * @author Thomas Risberg * @author Oliver Gierke * @author Patryk Wasik * @author Thomas Darimont + * @author Christoph Strobl */ public class QueryTests { @@ -213,4 +214,20 @@ public class QueryTests { assertThat(query.getRestrictedTypes().size(), is(1)); assertThat(query.getRestrictedTypes(), hasItems(Arrays.asList(SpecialDoc.class).toArray(new Class[0]))); } + + @Test // DATAMONGO-1421 + public void addCriteriaForSamePropertyMultipleTimesShouldThrowAndSafelySerializeErrorMessage() { + + exception.expect(InvalidMongoDbApiUsageException.class); + exception.expectMessage("second 'value' criteria"); + exception.expectMessage("already contains '{ \"value\" : { $java : VAL_1 } }'"); + + Query query = new Query(); + query.addCriteria(where("value").is(EnumType.VAL_1)); + query.addCriteria(where("value").is(EnumType.VAL_2)); + } + + enum EnumType { + VAL_1, VAL_2 + } }