diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java index 43a0592df0..c637f54c4b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java @@ -20,8 +20,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -59,6 +61,7 @@ * @author Mark Paluch * @author Andreas Zink * @author Ziemowit Stolarczyk + * @author Clément Petit */ public class Criteria implements CriteriaDefinition { @@ -976,9 +979,9 @@ private boolean isEqual(Object left, Object right) { return right == null; } - if (Pattern.class.isInstance(left)) { + if (left instanceof Pattern) { - if (!Pattern.class.isInstance(right)) { + if (!(right instanceof Pattern)) { return false; } @@ -989,6 +992,46 @@ private boolean isEqual(Object left, Object right) { && leftPattern.flags() == rightPattern.flags(); } + if (left instanceof Document) { + if (!(right instanceof Document)) { + return false; + } + Document leftDocument = (Document) left; + Document rightDocument = (Document) right; + Iterator leftIterator = leftDocument.entrySet().iterator(); + Iterator rightIterator = rightDocument.entrySet().iterator(); + + while (leftIterator.hasNext() && rightIterator.hasNext()) { + Map.Entry leftEntry = (Map.Entry)leftIterator.next(); + Map.Entry rightEntry = (Map.Entry)rightIterator.next(); + if (!isEqual(leftEntry.getKey(), rightEntry.getKey())) { + return false; + } + if (!isEqual(leftEntry.getValue(), rightEntry.getValue())) { + return false; + } + } + return !leftIterator.hasNext() && !rightIterator.hasNext(); + } + + if (Collection.class.isAssignableFrom(left.getClass())) { + if (!Collection.class.isAssignableFrom(right.getClass())) { + return false; + } + + Collection leftCollection = (Collection) left; + Collection rightCollection = (Collection) right; + Iterator leftIterator = leftCollection.iterator(); + Iterator rightIterator = rightCollection.iterator(); + + while (leftIterator.hasNext() && rightIterator.hasNext()) { + if (!isEqual(leftIterator.next(), rightIterator.next())) { + return false; + } + } + return !leftIterator.hasNext() && !rightIterator.hasNext(); + } + return ObjectUtils.nullSafeEquals(left, right); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java index 01e3b18832..6d0c3a167b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java @@ -38,6 +38,7 @@ * @author Christoph Strobl * @author Andreas Zink * @author Ziemowit Stolarczyk + * @author Clément Petit */ public class CriteriaUnitTests { @@ -353,9 +354,33 @@ public void shouldAppendBitsAnySetWithPositionListCorrectly() { @Test // DATAMONGO-2002 public void shouldEqualForSamePattern() { + Criteria left = new Criteria("field").regex("foo"); + Criteria right = new Criteria("field").regex("foo"); + + assertThat(left).isEqualTo(right); + } + + @Test // DATAMONGO-2002 + public void shouldEqualForSamePatternAndFlags() { + Criteria left = new Criteria("field").regex("foo", "iu"); Criteria right = new Criteria("field").regex("foo"); assertThat(left).isNotEqualTo(right); } + + @Test // GH-3414 + public void shouldEqualForNestedPattern() { + + Criteria left = new Criteria("a").orOperator( + new Criteria("foo").regex("value", "i"), + new Criteria("bar").regex("value") + ); + Criteria right = new Criteria("a").orOperator( + new Criteria("foo").regex("value", "i"), + new Criteria("bar").regex("value") + ); + + assertThat(left).isEqualTo(right); + } }