diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java index 5a05ed7b6..02f221034 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java @@ -109,7 +109,7 @@ public abstract class SerializationUtils { * printing raw {@link Document}s containing complex values before actually converting them into Mongo native types. * * @param value - * @return + * @return the serialized value or {@literal null}. */ @Nullable public static String serializeToJsonSafely(@Nullable Object value) { @@ -119,14 +119,15 @@ public abstract class SerializationUtils { } try { - return JSON.serialize(value); + return value instanceof Document ? ((Document) value).toJson() : JSON.serialize(value); } catch (Exception e) { + if (value instanceof Collection) { return toString((Collection) value); } else if (value instanceof Map) { return toString((Map) value); } else { - return String.format("{ $java : %s }", value.toString()); + return String.format("{ \"$java\" : %s }", value.toString()); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java index fdc9075c4..a5209035a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java @@ -485,7 +485,14 @@ public class Update { */ @Override public String toString() { - return SerializationUtils.serializeToJsonSafely(getUpdateObject()); + + Document doc = getUpdateObject(); + + if (isIsolated()) { + doc.append("$isolated", 1); + } + + return SerializationUtils.serializeToJsonSafely(doc); } /** @@ -510,7 +517,16 @@ public class Update { this.modifiers.put(modifier.getKey(), modifier); } - /* (non-Javadoc) + /** + * @return true if no modifiers present. + * @since 2.0 + */ + public boolean isEmpty() { + return modifiers.isEmpty(); + } + + /* + * (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override @@ -536,6 +552,11 @@ public class Update { return this.modifiers.equals(that.modifiers); } + + @Override + public String toString() { + return SerializationUtils.serializeToJsonSafely(this.modifiers); + } } /** @@ -554,6 +575,14 @@ public class Update { * @return value to be sent with command */ Object getValue(); + + /** + * @return a safely serialized JSON representation. + * @since 2.0 + */ + default String toJsonString() { + return SerializationUtils.serializeToJsonSafely(Collections.singletonMap(getKey(), getValue())); + } } /** @@ -627,6 +656,11 @@ public class Update { return nullSafeEquals(values, ((Each) that).values); } + + @Override + public String toString() { + return toJsonString(); + } } /** @@ -652,6 +686,11 @@ public class Update { public Object getValue() { return position; } + + @Override + public String toString() { + return toJsonString(); + } } /** @@ -685,6 +724,11 @@ public class Update { public Object getValue() { return this.count; } + + @Override + public String toString() { + return toJsonString(); + } } /** @@ -746,6 +790,11 @@ public class Update { public Object getValue() { return this.sort; } + + @Override + public String toString() { + return toJsonString(); + } } /** @@ -867,7 +916,13 @@ public class Update { * @return never {@literal null}. */ public Update value(Object value) { - return Update.this.push(key, value); + + if (this.modifiers.isEmpty()) { + return Update.this.push(key, value); + } + + this.modifiers.addModifier(new Each(Collections.singletonList(value))); + return Update.this.push(key, this.modifiers); } /* diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SerializationUtilsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SerializationUtilsUnitTests.java index deb235689..41e7fa085 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SerializationUtilsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SerializationUtilsUnitTests.java @@ -41,7 +41,7 @@ public class SerializationUtilsUnitTests { public void writesSimpleDocument() { Document document = new Document("foo", "bar"); - assertThat(serializeToJsonSafely(document), is("{ \"foo\" : \"bar\"}")); + assertThat(serializeToJsonSafely(document), is("{ \"foo\" : \"bar\" }")); } @Test @@ -49,7 +49,7 @@ public class SerializationUtilsUnitTests { Document document = new Document("foo", new Complex()); assertThat(serializeToJsonSafely(document), - startsWith("{ \"foo\" : { $java : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex")); + startsWith("{ \"foo\" : { \"$java\" : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex")); } @Test @@ -58,7 +58,7 @@ public class SerializationUtilsUnitTests { Document document = new Document("foo", Arrays.asList("bar", new Complex())); Matcher expectedOutput = allOf( startsWith( - "{ \"foo\" : [ \"bar\", { $java : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"), + "{ \"foo\" : [ \"bar\", { \"$java\" : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"), endsWith(" } ] }")); assertThat(serializeToJsonSafely(document), is(expectedOutput)); } 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 4201c5378..35410b853 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 @@ -210,7 +210,7 @@ public class QueryTests { Query query = new Query(where("name").is("foo")).restrict(SpecialDoc.class); assertThat(query.toString(), is( - "Query: { \"name\" : \"foo\", \"_$RESTRICTED_TYPES\" : [ { $java : class org.springframework.data.mongodb.core.SpecialDoc } ] }, Fields: { }, Sort: { }")); + "Query: { \"name\" : \"foo\", \"_$RESTRICTED_TYPES\" : [ { \"$java\" : class org.springframework.data.mongodb.core.SpecialDoc } ] }, Fields: { }, Sort: { }")); assertThat(query.getRestrictedTypes(), is(notNullValue())); assertThat(query.getRestrictedTypes().size(), is(1)); assertThat(query.getRestrictedTypes(), hasItems(Arrays.asList(SpecialDoc.class).toArray(new Class[0]))); @@ -221,7 +221,7 @@ public class QueryTests { exception.expect(InvalidMongoDbApiUsageException.class); exception.expectMessage("second 'value' criteria"); - exception.expectMessage("already contains '{ \"value\" : { $java : VAL_1 } }'"); + exception.expectMessage("already contains '{ \"value\" : { \"$java\" : VAL_1 } }'"); Query query = new Query(); query.addCriteria(where("value").is(EnumType.VAL_1)); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java index b140684d5..2acf8ef9c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java @@ -26,6 +26,7 @@ import org.bson.Document; import org.joda.time.DateTime; import org.junit.Test; import org.springframework.data.mongodb.core.DocumentTestUtils; +import org.springframework.data.mongodb.core.query.Update.Position; /** * Test cases for {@link Update}. @@ -476,4 +477,18 @@ public class UpdateTests { assertThat(update.getUpdateObject(), equalTo(new Document("$min", new Document("key", date)))); } + + @Test // DATAMONGO-1777 + public void toStringShouldPrettyPrintModifiers() { + + assertThat(new Update().push("key").atPosition(Position.FIRST).value("Arya").toString(), is(equalTo( + "{ \"$push\" : { \"key\" : { \"$java\" : { \"$position\" : { \"$java\" : { \"$position\" : 0} }, \"$each\" : { \"$java\" : { \"$each\" : [ \"Arya\"]} } } } } }"))); + } + + @Test // DATAMONGO-1777 + public void toStringConsidersIsolated() { + + assertThat(new Update().set("key", "value").isolated().toString(), + is(equalTo("{ \"$set\" : { \"key\" : \"value\" }, \"$isolated\" : 1 }"))); + } }