From c3a5f325d24307473fe988c30e7722f51d4b9ff2 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 27 Oct 2022 10:15:33 +0200 Subject: [PATCH] Use correct `boolean` type for JSON Schema creation. We now use the correct JSON type boolean again when creating schemas. Furthermore, we use the bool type for MongoDB $type queries. Closes #4220 --- .../data/mongodb/core/query/Criteria.java | 2 +- .../mongodb/core/schema/JsonSchemaObject.java | 2 +- .../mongodb/core/JsonSchemaQueryTests.java | 26 +++++++++++ ...appingMongoJsonSchemaCreatorUnitTests.java | 2 +- .../mongodb/core/query/CriteriaUnitTests.java | 43 +++++++++---------- .../schema/JsonSchemaObjectUnitTests.java | 6 +-- 6 files changed, 52 insertions(+), 29 deletions(-) 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 a08c5f6e2f..adccc1b6b4 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 @@ -450,7 +450,7 @@ public Criteria type(Collection types) { Assert.notNull(types, "Types must not be null!"); - criteria.put("$type", types.stream().map(Type::value).collect(Collectors.toList())); + criteria.put("$type", types.stream().map(Type::toBsonType).map(Type::value).collect(Collectors.toList())); return this; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java index 3e03f41b14..0ca18caa5c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java @@ -295,7 +295,7 @@ interface Type { Type OBJECT = jsonTypeOf("object"); Type ARRAY = jsonTypeOf("array"); Type NUMBER = jsonTypeOf("number"); - Type BOOLEAN = jsonTypeOf("bool"); + Type BOOLEAN = jsonTypeOf("boolean"); Type STRING = jsonTypeOf("string"); Type NULL = jsonTypeOf("null"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java index c98866d7fd..bae9484c0d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java @@ -29,6 +29,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Field; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.MongoTemplateExtension; @@ -83,6 +85,28 @@ public void setUp() { template.save(jellyBelly); template.save(roseSpringHeart); template.save(kazmardBoombub); + + } + + @Test // DATAMONGO-1835 + public void createsWorkingSchema() { + + try { + template.dropCollection("person_schema"); + } catch (Exception e) {} + + MongoJsonSchema schema = MongoJsonSchemaCreator.create(template.getConverter()).createSchemaFor(Person.class); + + template.createCollection("person_schema", CollectionOptions.empty().schema(schema)); + } + + @Test // DATAMONGO-1835 + public void queriesBooleanType() { + + MongoJsonSchema schema = MongoJsonSchema.builder().properties(JsonSchemaProperty.bool("alive")).build(); + + assertThat(template.find(query(matchingDocumentStructure(schema)), Person.class)).hasSize(3); + assertThat(template.find(query(Criteria.where("alive").type(Type.BOOLEAN)), Person.class)).hasSize(3); } @Test // DATAMONGO-1835 @@ -201,6 +225,8 @@ static class Person { Gender gender; Address address; Object value; + + boolean alive; } @Data diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreatorUnitTests.java index ccf3b71288..30ff5b6ff0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreatorUnitTests.java @@ -179,7 +179,7 @@ enum JustSomeEnum { " 're-named-property' : { 'type' : 'string' }," + // " 'retypedProperty' : { 'bsonType' : 'javascript' }," + // " 'primitiveInt' : { 'bsonType' : 'int' }," + // - " 'booleanProperty' : { 'type' : 'bool' }," + // + " 'booleanProperty' : { 'type' : 'boolean' }," + // " 'longProperty' : { 'bsonType' : 'long' }," + // " 'intProperty' : { 'bsonType' : 'int' }," + // " 'dateProperty' : { 'bsonType' : 'date' }," + // 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 468e1bf5d2..febb21c423 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 @@ -23,11 +23,11 @@ import org.bson.Document; import org.junit.Test; - import org.springframework.data.geo.Point; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.data.mongodb.core.geo.GeoJsonLineString; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; +import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; /** @@ -90,8 +90,7 @@ public void equalIfCriteriaMatches() { @Test // GH-3286 public void shouldBuildCorrectAndOperator() { - Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true), - Criteria.where("y").is(42), + Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true), Criteria.where("y").is(42), Criteria.where("z").is("value")); Criteria criteria = Criteria.where("foo").is("bar").andOperator(operatorCriteria); @@ -103,8 +102,7 @@ public void shouldBuildCorrectAndOperator() { @Test // GH-3286 public void shouldBuildCorrectOrOperator() { - Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true), - Criteria.where("y").is(42), + Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true), Criteria.where("y").is(42), Criteria.where("z").is("value")); Criteria criteria = Criteria.where("foo").is("bar").orOperator(operatorCriteria); @@ -116,8 +114,7 @@ public void shouldBuildCorrectOrOperator() { @Test // GH-3286 public void shouldBuildCorrectNorOperator() { - Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true), - Criteria.where("y").is(42), + Collection operatorCriteria = Arrays.asList(Criteria.where("x").is(true), Criteria.where("y").is(42), Criteria.where("z").is("value")); Criteria criteria = Criteria.where("foo").is("bar").norOperator(operatorCriteria); @@ -205,6 +202,14 @@ public void getCriteriaObjectShouldRespectNotWhenNoKeyPresent() { assertThat(document).isEqualTo(new Document().append("$not", new Document("$lt", "foo"))); } + @Test // GH-4220 + public void usesCorrectBsonType() { + + Document document = new Criteria("foo").type(Type.BOOLEAN).getCriteriaObject(); + + assertThat(document).containsEntry("foo.$type", Collections.singletonList("bool")); + } + @Test // DATAMONGO-1135 public void geoJsonTypesShouldBeWrappedInGeometry() { @@ -302,8 +307,7 @@ public void shouldAppendBitsAllClearWithIntBitmaskCorrectly() { Criteria numericBitmaskCriteria = new Criteria("field").bits().allClear(0b101); - assertThat(numericBitmaskCriteria.getCriteriaObject()) - .isEqualTo("{ \"field\" : { \"$bitsAllClear\" : 5} }"); + assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAllClear\" : 5} }"); } @Test // DATAMONGO-1808 @@ -320,8 +324,7 @@ public void shouldAppendBitsAllSetWithIntBitmaskCorrectly() { Criteria numericBitmaskCriteria = new Criteria("field").bits().allSet(0b101); - assertThat(numericBitmaskCriteria.getCriteriaObject()) - .isEqualTo("{ \"field\" : { \"$bitsAllSet\" : 5} }"); + assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAllSet\" : 5} }"); } @Test // DATAMONGO-1808 @@ -338,8 +341,7 @@ public void shouldAppendBitsAnyClearWithIntBitmaskCorrectly() { Criteria numericBitmaskCriteria = new Criteria("field").bits().anyClear(0b101); - assertThat(numericBitmaskCriteria.getCriteriaObject()) - .isEqualTo("{ \"field\" : { \"$bitsAnyClear\" : 5} }"); + assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAnyClear\" : 5} }"); } @Test // DATAMONGO-1808 @@ -356,8 +358,7 @@ public void shouldAppendBitsAnySetWithIntBitmaskCorrectly() { Criteria numericBitmaskCriteria = new Criteria("field").bits().anySet(0b101); - assertThat(numericBitmaskCriteria.getCriteriaObject()) - .isEqualTo("{ \"field\" : { \"$bitsAnySet\" : 5} }"); + assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAnySet\" : 5} }"); } @Test // DATAMONGO-1808 @@ -429,14 +430,10 @@ public void shouldEqualForSamePatternAndFlags() { @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") - ); + 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); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/JsonSchemaObjectUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/JsonSchemaObjectUnitTests.java index 61c076b1c8..6af8429f48 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/JsonSchemaObjectUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/JsonSchemaObjectUnitTests.java @@ -133,7 +133,7 @@ void objectObjectShouldRenderPropertiesCorrectly() { .append("description", "Must be an object defining restrictions for name, active.").append("properties", new Document("name", new Document("type", "string") .append("description", "Must be a string with length unbounded-10].").append("maxLength", 10)) - .append("active", new Document("type", "bool"))); + .append("active", new Document("type", "boolean"))); assertThat(object().generatedDescription() .properties(JsonSchemaProperty.string("name").maxLength(10).generatedDescription(), @@ -266,7 +266,7 @@ void numberObjectShouldRenderMinimumCorrectly() { void arrayObjectShouldRenderItemsCorrectly() { assertThat(array().items(Arrays.asList(string(), bool())).toDocument()).isEqualTo(new Document("type", "array") - .append("items", Arrays.asList(new Document("type", "string"), new Document("type", "bool")))); + .append("items", Arrays.asList(new Document("type", "string"), new Document("type", "boolean")))); } @Test // DATAMONGO-2613 @@ -316,7 +316,7 @@ void arrayObjectShouldRenderAdditionalItemsItemsCorrectly() { void booleanShouldRenderCorrectly() { assertThat(bool().generatedDescription().toDocument()) - .isEqualTo(new Document("type", "bool").append("description", "Must be a boolean.")); + .isEqualTo(new Document("type", "boolean").append("description", "Must be a boolean.")); } // -----------------