From 4acc473825930b66181fe37a4b452621f4d31fc5 Mon Sep 17 00:00:00 2001 From: Mikhail Kaduchka Date: Thu, 14 Mar 2019 00:36:20 +0100 Subject: [PATCH] DATAMONGO-2228 - Fixed loosing branches in AND expressions (MongodbDocumentSerializer) --- .../support/MongodbDocumentSerializer.java | 5 ++- .../SpringDataMongodbSerializerUnitTests.java | 42 ++++++++++++------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongodbDocumentSerializer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongodbDocumentSerializer.java index 210cb355ca..a1503b1985 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongodbDocumentSerializer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongodbDocumentSerializer.java @@ -49,6 +49,7 @@ * @author laimw * @author Mark Paluch * @author Christoph Strobl + * @author Mikhail Kaduchka * @since 2.1 */ abstract class MongodbDocumentSerializer implements Visitor { @@ -184,8 +185,8 @@ public Object visit(Operation expr, Void context) { Map lhs = (Map) handle(expr.getArg(0)); Map rhs = (Map) handle(expr.getArg(1)); - LinkedHashSet> lhs2 = new LinkedHashSet<>(lhs.entrySet()); - lhs2.retainAll(rhs.entrySet()); + LinkedHashSet lhs2 = new LinkedHashSet<>(lhs.keySet()); + lhs2.retainAll(rhs.keySet()); if (lhs2.isEmpty()) { lhs.putAll(rhs); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java index b7d6add63c..5ca8c9bb7f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java @@ -15,17 +15,11 @@ */ package org.springframework.data.mongodb.repository.support; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.springframework.data.mongodb.core.DocumentTestUtils.*; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.PredicateOperation; +import com.querydsl.core.types.dsl.*; import org.bson.Document; import org.bson.types.ObjectId; -import org.hamcrest.collection.IsIterableContainingInOrder; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -43,11 +37,13 @@ import org.springframework.data.mongodb.repository.QAddress; import org.springframework.data.mongodb.repository.QPerson; -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.core.types.dsl.BooleanOperation; -import com.querydsl.core.types.dsl.PathBuilder; -import com.querydsl.core.types.dsl.SimplePath; -import com.querydsl.core.types.dsl.StringPath; +import java.util.Collections; + +import static com.querydsl.core.types.ExpressionUtils.path; +import static com.querydsl.core.types.ExpressionUtils.predicate; +import static com.querydsl.core.types.dsl.Expressions.constant; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertThat; /** * Unit tests for {@link SpringDataMongodbSerializer}. @@ -55,6 +51,7 @@ * @author Oliver Gierke * @author Christoph Strobl * @author Mark Paluch + * @author Mikhail Kaduchka */ @RunWith(MockitoJUnitRunner.class) public class SpringDataMongodbSerializerUnitTests { @@ -163,6 +160,23 @@ public void shouldRemarshallListsAndDocuments() { + "\"$ne\" : \"\"}}} , { \"firstname\" : { \"$not\" : { \"$regex\" : \".*\\\\Qfoo\\\\E.*\" , \"$options\" : \"i\"}}}]}")))); } + @Test // DATAMONGO-2228 + public void retainsOpsInAndExpression() { + + PredicateOperation testExpression = predicate(Ops.AND, + predicate(Ops.OR, + predicate(Ops.EQ, path(Object.class, "firstname"), constant("John")), + predicate(Ops.EQ, path(Object.class, "firstname"), constant("Sarah"))), + predicate(Ops.OR, + predicate(Ops.EQ, path(Object.class, "lastname"), constant("Smith")), + predicate(Ops.EQ, path(Object.class, "lastname"), constant("Connor"))) + ); + + Document result = (Document) serializer.visit(testExpression, null); + + assertThat(result.toJson(), is("{\"$and\": [{\"$or\": [{\"firstname\": \"John\"}, {\"firstname\": \"Sarah\"}]}, {\"$or\": [{\"lastname\": \"Smith\"}, {\"lastname\": \"Connor\"}]}]}")); + } + class Address { String id; String street;