types) {
+
+ Assert.notNull(types, "Types must not be null!");
+
+ criteria.put("$type", types.stream().map(Type::value).collect(Collectors.toList()));
return this;
}
@@ -669,67 +684,103 @@ public class Criteria implements CriteriaDefinition {
}
/**
- * Creates an 'or' criteria using the $or operator for all of the provided criteria
- *
- * Note that mongodb doesn't support an $or operator to be wrapped in a $not operator.
+ * Creates a criteria using the {@code $or} operator for all of the provided criteria.
*
+ * Note that MongoDB doesn't support an {@code $nor} operator to be wrapped in a {@code $not} operator.
*
- * @throws IllegalArgumentException if {@link #orOperator(Criteria...)} follows a not() call directly.
+ * @throws IllegalArgumentException if this method follows a {@link #not()} call directly.
* @param criteria must not be {@literal null}.
* @return this.
*/
public Criteria orOperator(Criteria... criteria) {
+
+ Assert.notNull(criteria, "Criteria must not be null!");
+
return orOperator(Arrays.asList(criteria));
}
/**
- * {@link #orOperator(Criteria...)}
+ * Creates a criteria using the {@code $or} operator for all of the provided criteria.
+ *
+ * Note that MongoDB doesn't support an {@code $nor} operator to be wrapped in a {@code $not} operator.
+ *
+ * @throws IllegalArgumentException if this method follows a {@link #not()} call directly.
+ * @param criteria must not be {@literal null}.
+ * @return this.
+ * @since 3.2
*/
public Criteria orOperator(Collection criteria) {
+
+ Assert.notNull(criteria, "Criteria must not be null!");
+
BasicDBList bsonList = createCriteriaList(criteria);
return registerCriteriaChainElement(new Criteria("$or").is(bsonList));
}
/**
- * Creates a 'nor' criteria using the $nor operator for all of the provided criteria.
- *
- * Note that mongodb doesn't support an $nor operator to be wrapped in a $not operator.
+ * Creates a criteria using the {@code $nor} operator for all of the provided criteria.
*
+ * Note that MongoDB doesn't support an {@code $nor} operator to be wrapped in a {@code $not} operator.
*
- * @throws IllegalArgumentException if {@link #norOperator(Criteria...)} follows a not() call directly.
+ * @throws IllegalArgumentException if this method follows a {@link #not()} call directly.
* @param criteria must not be {@literal null}.
* @return this.
*/
public Criteria norOperator(Criteria... criteria) {
+
+ Assert.notNull(criteria, "Criteria must not be null!");
+
return norOperator(Arrays.asList(criteria));
}
/**
- * {@link #norOperator(Criteria...)}
+ * Creates a criteria using the {@code $nor} operator for all of the provided criteria.
+ *
+ * Note that MongoDB doesn't support an {@code $nor} operator to be wrapped in a {@code $not} operator.
+ *
+ * @throws IllegalArgumentException if this method follows a {@link #not()} call directly.
+ * @param criteria must not be {@literal null}.
+ * @return this.
+ * @since 3.2
*/
public Criteria norOperator(Collection criteria) {
+
+ Assert.notNull(criteria, "Criteria must not be null!");
+
BasicDBList bsonList = createCriteriaList(criteria);
return registerCriteriaChainElement(new Criteria("$nor").is(bsonList));
}
/**
- * Creates an 'and' criteria using the $and operator for all of the provided criteria.
- *
- * Note that mongodb doesn't support an $and operator to be wrapped in a $not operator.
+ * Creates a criteria using the {@code $and} operator for all of the provided criteria.
*
+ * Note that MongoDB doesn't support an {@code $and} operator to be wrapped in a {@code $not} operator.
*
- * @throws IllegalArgumentException if {@link #andOperator(Criteria...)} follows a not() call directly.
+ * @throws IllegalArgumentException if this method follows a {@link #not()} call directly.
* @param criteria must not be {@literal null}.
* @return this.
*/
public Criteria andOperator(Criteria... criteria) {
+
+ Assert.notNull(criteria, "Criteria must not be null!");
+
return andOperator(Arrays.asList(criteria));
}
/**
- * {@link #andOperator(Criteria...)}
+ * Creates a criteria using the {@code $and} operator for all of the provided criteria.
+ *
+ * Note that MongoDB doesn't support an {@code $and} operator to be wrapped in a {@code $not} operator.
+ *
+ * @throws IllegalArgumentException if this method follows a {@link #not()} call directly.
+ * @param criteria must not be {@literal null}.
+ * @return this.
+ * @since 3.2
*/
public Criteria andOperator(Collection criteria) {
+
+ Assert.notNull(criteria, "Criteria must not be null!");
+
BasicDBList bsonList = createCriteriaList(criteria);
return registerCriteriaChainElement(new Criteria("$and").is(bsonList));
}
@@ -832,11 +883,13 @@ public class Criteria implements CriteriaDefinition {
}
private void setValue(Document document, String key, Object value) {
+
Object existing = document.get(key);
+
if (existing == null) {
document.put(key, value);
} else {
- throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDocument, "
+ throw new InvalidMongoDbApiUsageException("Due to limitations of the org.bson.Document, "
+ "you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. "
+ "Criteria already contains '" + key + " : " + existing + "'.");
}
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 51257d549..01e3b1883 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
@@ -31,6 +31,8 @@ import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
/**
+ * Unit tests for {@link Criteria}.
+ *
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
@@ -82,52 +84,43 @@ public class CriteriaUnitTests {
assertThat(right).isNotEqualTo(left);
}
- @Test
+ @Test // GH-3286
public void shouldBuildCorrectAndOperator() {
- //given
+
Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true),
Criteria.where("y").is(42),
Criteria.where("z").is("value"));
- Document expectedResult = Document
- .parse("{\"$and\":[{\"x\":true}, {\"y\":42}, {\"z\":\"value\"}], \"foo\":\"bar\"}");
- //when
Criteria criteria = Criteria.where("foo").is("bar").andOperator(operatorCriteria);
- //then
- assertThat(criteria.getCriteriaObject()).isEqualTo(expectedResult);
+ assertThat(criteria.getCriteriaObject())
+ .isEqualTo("{\"$and\":[{\"x\":true}, {\"y\":42}, {\"z\":\"value\"}], \"foo\":\"bar\"}");
}
- @Test
+ @Test // GH-3286
public void shouldBuildCorrectOrOperator() {
- //given
+
Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true),
Criteria.where("y").is(42),
Criteria.where("z").is("value"));
- Document expectedResult = Document
- .parse("{\"$or\":[{\"x\":true}, {\"y\":42}, {\"z\":\"value\"}], \"foo\":\"bar\"}");
- //when
Criteria criteria = Criteria.where("foo").is("bar").orOperator(operatorCriteria);
- //then
- assertThat(criteria.getCriteriaObject()).isEqualTo(expectedResult);
+ assertThat(criteria.getCriteriaObject())
+ .isEqualTo("{\"$or\":[{\"x\":true}, {\"y\":42}, {\"z\":\"value\"}], \"foo\":\"bar\"}");
}
- @Test
+ @Test // GH-3286
public void shouldBuildCorrectNorOperator() {
- //given
+
Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true),
Criteria.where("y").is(42),
Criteria.where("z").is("value"));
- Document expectedResult = Document
- .parse("{\"$nor\":[{\"x\":true}, {\"y\":42}, {\"z\":\"value\"}], \"foo\":\"bar\"}");
- //when
Criteria criteria = Criteria.where("foo").is("bar").norOperator(operatorCriteria);
- //then
- assertThat(criteria.getCriteriaObject()).isEqualTo(expectedResult);
+ assertThat(criteria.getCriteriaObject())
+ .isEqualTo("{\"$nor\":[{\"x\":true}, {\"y\":42}, {\"z\":\"value\"}], \"foo\":\"bar\"}");
}
@Test // DATAMONGO-507