diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java
index 212d5edd3..815a68994 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java
@@ -21,12 +21,11 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
-import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
-import org.springframework.data.mapping.SimplePropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.mapping.Field;
+import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty;
import org.springframework.data.mongodb.core.schema.JsonSchemaObject;
@@ -35,7 +34,6 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema.MongoJsonSchemaBuilder;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@@ -45,26 +43,28 @@ import org.springframework.util.ObjectUtils;
* {@link MongoJsonSchemaCreator} implementation using both {@link MongoConverter} and {@link MappingContext} to obtain
* domain type meta information which considers {@link org.springframework.data.mongodb.core.mapping.Field field names}
* and {@link org.springframework.data.mongodb.core.convert.MongoCustomConversions custom conversions}.
- *
+ *
* @author Christoph Strobl
+ * @author Mark Paluch
* @since 2.2
*/
class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
- private MongoConverter converter;
- private MappingContext mappingContext;
+ private final MongoConverter converter;
+ private final MappingContext, MongoPersistentProperty> mappingContext;
/**
* Create a new instance of {@link MappingMongoJsonSchemaCreator}.
*
* @param converter must not be {@literal null}.
*/
+ @SuppressWarnings("unchecked")
MappingMongoJsonSchemaCreator(MongoConverter converter) {
Assert.notNull(converter, "Converter must not be null!");
this.converter = converter;
- this.mappingContext = converter.getMappingContext();
-
+ this.mappingContext = (MappingContext, MongoPersistentProperty>) converter
+ .getMappingContext();
}
/*
@@ -74,7 +74,7 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
@Override
public MongoJsonSchema createSchemaFor(Class> type) {
- PersistentEntity, ?> entity = mappingContext.getPersistentEntity(type);
+ MongoPersistentEntity> entity = mappingContext.getRequiredPersistentEntity(type);
MongoJsonSchemaBuilder schemaBuilder = MongoJsonSchema.builder();
List schemaProperties = computePropertiesForEntity(Collections.emptyList(), entity);
@@ -84,35 +84,33 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
}
- private List computePropertiesForEntity(List path,
- PersistentEntity, ?> entity) {
+ private List computePropertiesForEntity(List path,
+ MongoPersistentEntity> entity) {
List schemaProperties = new ArrayList<>();
- entity.doWithProperties((SimplePropertyHandler) nested -> {
- ArrayList currentPath = new ArrayList<>(path);
+ for (MongoPersistentProperty nested : entity) {
+
+ List currentPath = new ArrayList<>(path);
if (path.contains(nested)) { // cycle guard
schemaProperties.add(createSchemaProperty(computePropertyFieldName(CollectionUtils.lastElement(currentPath)),
Object.class, false));
- return;
+ break;
}
currentPath.add(nested);
- JsonSchemaProperty jsonSchemaProperty = computeSchemaForProperty(currentPath, entity);
- if (jsonSchemaProperty != null) {
- schemaProperties.add(jsonSchemaProperty);
- }
- });
+ schemaProperties.add(computeSchemaForProperty(currentPath));
+ }
return schemaProperties;
}
- private JsonSchemaProperty computeSchemaForProperty(List path, PersistentEntity, ?> parent) {
+ private JsonSchemaProperty computeSchemaForProperty(List path) {
- PersistentProperty property = CollectionUtils.lastElement(path);
+ MongoPersistentProperty property = CollectionUtils.lastElement(path);
- boolean required = isRequiredProperty(parent, property);
+ boolean required = isRequiredProperty(property);
Class> rawTargetType = computeTargetType(property); // target type before conversion
Class> targetType = converter.getTypeMapper().getWriteTargetTypeFor(rawTargetType); // conversion target type
@@ -133,12 +131,12 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
return createSchemaProperty(fieldName, targetType, required);
}
- private JsonSchemaProperty createObjectSchemaPropertyForEntity(List path,
- PersistentProperty property, boolean required) {
+ private JsonSchemaProperty createObjectSchemaPropertyForEntity(List path,
+ MongoPersistentProperty property, boolean required) {
ObjectJsonSchemaProperty target = JsonSchemaProperty.object(property.getName());
List nestedProperties = computePropertiesForEntity(path,
- mappingContext.getPersistentEntity(property));
+ mappingContext.getRequiredPersistentEntity(property));
return createPotentiallyRequiredSchemaProperty(
target.properties(nestedProperties.toArray(new JsonSchemaProperty[0])), required);
@@ -147,6 +145,7 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
private JsonSchemaProperty createEnumSchemaProperty(String fieldName, Class> targetType, boolean required) {
List
- *
+ *
* @author Christoph Strobl
* @since 2.2
*/
@@ -66,7 +67,7 @@ public interface MongoJsonSchemaCreator {
* @param mongoConverter must not be {@literal null}.
* @return new instance of {@link MongoJsonSchemaCreator}.
*/
- static MongoJsonSchemaCreator jsonSchemaCreator(MongoConverter mongoConverter) {
+ static MongoJsonSchemaCreator create(MongoConverter mongoConverter) {
Assert.notNull(mongoConverter, "MongoConverter must not be null!");
return new MappingMongoJsonSchemaCreator(mongoConverter);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java
index ee3b9aaa2..b16681561 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java
@@ -15,14 +15,16 @@
*/
package org.springframework.data.mongodb.core.convert;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.function.Function;
+import java.util.function.UnaryOperator;
import org.bson.Document;
import org.bson.conversions.Bson;
+
+import org.springframework.data.convert.CustomConversions;
import org.springframework.data.convert.DefaultTypeMapper;
import org.springframework.data.convert.SimpleTypeInformationMapper;
import org.springframework.data.convert.TypeAliasAccessor;
@@ -59,29 +61,58 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper implements M
private final TypeAliasAccessor accessor;
private final @Nullable String typeKey;
- private Function, Class>> writeTarget = it -> it;
+ private UnaryOperator> writeTarget = UnaryOperator.identity();
+ /**
+ * Create a new {@link MongoTypeMapper} with fully-qualified type hints using {@code _class}.
+ */
public DefaultMongoTypeMapper() {
this(DEFAULT_TYPE_KEY);
}
+ /**
+ * Create a new {@link MongoTypeMapper} with fully-qualified type hints using {@code typeKey}.
+ *
+ * @param typeKey name of the field to read and write type hints. Can be {@literal null} to disable type hints.
+ */
public DefaultMongoTypeMapper(@Nullable String typeKey) {
- this(typeKey, Arrays.asList(new SimpleTypeInformationMapper()));
+ this(typeKey, Collections.singletonList(new SimpleTypeInformationMapper()));
}
+ /**
+ * Create a new {@link MongoTypeMapper} with fully-qualified type hints using {@code typeKey}.
+ *
+ * @param typeKey name of the field to read and write type hints. Can be {@literal null} to disable type hints.
+ * @param mappingContext the mapping context.
+ */
public DefaultMongoTypeMapper(@Nullable String typeKey,
MappingContext extends PersistentEntity, ?>, ?> mappingContext) {
this(typeKey, new DocumentTypeAliasAccessor(typeKey), mappingContext,
- Arrays.asList(new SimpleTypeInformationMapper()));
+ Collections.singletonList(new SimpleTypeInformationMapper()));
}
+ /**
+ * Create a new {@link MongoTypeMapper} with fully-qualified type hints using {@code typeKey}. Uses
+ * {@link UnaryOperator} to apply {@link CustomConversions}.
+ *
+ * @param typeKey name of the field to read and write type hints. Can be {@literal null} to disable type hints.
+ * @param mappingContext the mapping context to look up types using type hints.
+ * @see MappingMongoConverter#getWriteTarget(Class)
+ */
public DefaultMongoTypeMapper(@Nullable String typeKey,
- MappingContext extends PersistentEntity, ?>, ?> mappingContext, Function, Class>> writeTarget) {
+ MappingContext extends PersistentEntity, ?>, ?> mappingContext, UnaryOperator> writeTarget) {
this(typeKey, new DocumentTypeAliasAccessor(typeKey), mappingContext,
- Arrays.asList(new SimpleTypeInformationMapper()));
+ Collections.singletonList(new SimpleTypeInformationMapper()));
this.writeTarget = writeTarget;
}
+ /**
+ * Create a new {@link MongoTypeMapper} with fully-qualified type hints using {@code typeKey}. Uses
+ * {@link TypeInformationMapper} to map type hints.
+ *
+ * @param typeKey name of the field to read and write type hints. Can be {@literal null} to disable type hints.
+ * @param mappers
+ */
public DefaultMongoTypeMapper(@Nullable String typeKey, List extends TypeInformationMapper> mappers) {
this(typeKey, new DocumentTypeAliasAccessor(typeKey), null, mappers);
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
index ea1dd87cd..0d0e7a685 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
@@ -34,6 +34,7 @@ import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -122,7 +123,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
this.dbRefResolver = dbRefResolver;
this.mappingContext = mappingContext;
this.typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, mappingContext,
- this::computeWriteTarget);
+ this::getWriteTarget);
this.idMapper = new QueryMapper(this);
this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE);
@@ -672,7 +673,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (!property.isDbReference()) {
if (property.hasExplicitWriteTarget()) {
- return writeCollectionInternal(collection, new HijackedTypeInformation<>(property), new ArrayList<>());
+ return writeCollectionInternal(collection, new TypeInformationWrapper<>(property), new ArrayList<>());
}
return writeCollectionInternal(collection, property.getTypeInformation(), new BasicDBList());
}
@@ -1608,6 +1609,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @param ref
* @return
*/
+ @Nullable
Document readRef(DBRef ref) {
return dbRefResolver.fetch(ref);
}
@@ -1630,7 +1632,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @return
* @since 2.2
*/
- protected Class> computeWriteTarget(Class> source) {
+ public Class> getWriteTarget(Class> source) {
return conversions.getCustomWriteTarget(source).orElse(source);
}
@@ -1702,12 +1704,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
}
- private static class HijackedTypeInformation implements TypeInformation {
+ private static class TypeInformationWrapper implements TypeInformation {
private MongoPersistentProperty persistentProperty;
private TypeInformation> delegate;
- public HijackedTypeInformation(MongoPersistentProperty property) {
+ public TypeInformationWrapper(MongoPersistentProperty property) {
this.persistentProperty = property;
this.delegate = property.getTypeInformation();
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/FieldType.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/FieldType.java
index 544d497c2..f550e8a58 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/FieldType.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/FieldType.java
@@ -31,8 +31,9 @@ import org.bson.types.ObjectId;
*
* Bson types are identified by a {@code byte} {@link #getBsonType() value}. This enumeration typically returns the
* according bson type value except for {@link #IMPLICIT} which is a marker to derive the field type from a property.
- *
+ *
* @author Mark Paluch
+ * @author Christoph Strobl
* @since 2.2
* @see org.bson.BsonType
*/
@@ -67,7 +68,7 @@ public enum FieldType {
/**
* Returns the BSON type identifier. Can be {@code -1} if {@link FieldType} maps to a synthetic Bson type.
- *
+ *
* @return the BSON type identifier. Can be {@code -1} if {@link FieldType} maps to a synthetic Bson type.
*/
public int getBsonType() {
@@ -76,7 +77,7 @@ public enum FieldType {
/**
* Returns the Java class used to represent the type.
- *
+ *
* @return the Java class used to represent the type.
*/
public Class> getJavaClass() {
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 03b6fc27a..de77ee6b0 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
@@ -15,15 +15,17 @@
*/
package org.springframework.data.mongodb.core;
+import static org.springframework.data.mongodb.test.util.Assertions.*;
+
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
-import org.assertj.core.api.Assertions;
import org.bson.Document;
import org.junit.Before;
import org.junit.Test;
+
import org.springframework.data.annotation.Transient;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
@@ -34,10 +36,12 @@ import org.springframework.data.mongodb.core.mapping.FieldType;
import org.springframework.data.mongodb.core.mapping.MongoId;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
-import org.springframework.lang.Nullable;
/**
+ * Unit tests for {@link MappingMongoJsonSchemaCreator}.
+ *
* @author Christoph Strobl
+ * @author Mark Paluch
*/
public class MappingMongoJsonSchemaCreatorUnitTests {
@@ -58,52 +62,25 @@ public class MappingMongoJsonSchemaCreatorUnitTests {
MongoJsonSchema schema = schemaCreator.createSchemaFor(VariousFieldTypes.class);
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class))
- .isEqualTo(Document.parse(VARIOUS_FIELD_TYPES));
- }
-
- @Test // DATAMONGO-1849
- public void requiredCtorArgs() {
-
- MongoJsonSchema schema = schemaCreator.createSchemaFor(RequiredArgsCtor.class);
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class))
- .isEqualTo(Document.parse(REQUIRED_ARGS_CTOR));
- }
-
- @Test // DATAMONGO-1849
- public void withNestedObject() {
-
- MongoJsonSchema schema = schemaCreator.createSchemaFor(WithNestedDomainType.class);
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class))
- .isEqualTo(Document.parse(WITH_NESTED_DOMAIN_TYPE));
- }
-
- @Test // DATAMONGO-1849
- public void withNestedThatHasRequiredFieldsObject() {
-
- MongoJsonSchema schema = schemaCreator.createSchemaFor(WithNestedDomainTypeHavingRequiredCtor.class);
-
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class))
- .isEqualTo(Document.parse(WITH_NESTED_DOMAIN_TYPE_HAVING_REQUIRED_CTOR));
+ assertThat(schema.toDocument().get("$jsonSchema", Document.class)).isEqualTo(Document.parse(VARIOUS_FIELD_TYPES));
}
@Test // DATAMONGO-1849
public void withRemappedIdType() {
MongoJsonSchema schema = schemaCreator.createSchemaFor(WithExplicitMongoIdTypeMapping.class);
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class))
- .isEqualTo(Document.parse(WITH_EXPLICIT_MONGO_ID_TYPE_MAPPING));
+ assertThat(schema.toDocument().get("$jsonSchema", Document.class)).isEqualTo(WITH_EXPLICIT_MONGO_ID_TYPE_MAPPING);
}
@Test // DATAMONGO-1849
public void cyclic() {
MongoJsonSchema schema = schemaCreator.createSchemaFor(Cyclic.class);
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class)).isEqualTo(Document.parse(CYCLIC));
+ assertThat(schema.toDocument().get("$jsonSchema", Document.class)).isEqualTo(CYCLIC);
}
@Test // DATAMONGO-1849
- public void convterRegisterd() {
+ public void converterRegistered() {
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
MongoCustomConversions mcc = new MongoCustomConversions(
@@ -114,8 +91,8 @@ public class MappingMongoJsonSchemaCreatorUnitTests {
schemaCreator = new MappingMongoJsonSchemaCreator(converter);
MongoJsonSchema schema = schemaCreator.createSchemaFor(WithNestedDomainType.class);
- Assertions.assertThat(schema.toDocument().get("$jsonSchema", Document.class)).isEqualTo(Document.parse(
- "{ 'type' : 'object', 'properties' : { '_id' : { 'type' : 'object' }, 'nested' : { 'type' : 'object' } } }"));
+ assertThat(schema.toDocument().get("$jsonSchema", Document.class)).isEqualTo(
+ "{ 'type' : 'object', 'properties' : { '_id' : { 'type' : 'object' }, 'nested' : { 'type' : 'object' } } }");
}
// --> TYPES AND JSON
@@ -171,32 +148,6 @@ public class MappingMongoJsonSchemaCreatorUnitTests {
JustSomeEnum enumProperty;
}
- // --> REQUIRED ARGS (CTOR)
-
- static final String REQUIRED_ARGS_CTOR = "" + //
- "{" + //
- " 'type' : 'object'," + //
- " 'required' : ['requiredCtorArg']," + //
- " 'properties' : {" + //
- " 'requiredCtorArg' : { 'type' : 'string' }," + //
- " 'nullableCtorArg' : { 'type' : 'string' }," + //
- " 'optionalArg' : { 'type' : 'string' }" + //
- " }" + //
- "}";
-
- static class RequiredArgsCtor {
-
- String requiredCtorArg;
- @Nullable String nullableCtorArg;
- String optionalArg;
-
- public RequiredArgsCtor(String requiredCtorArg, @Nullable String nullableCtorArg) {
-
- this.requiredCtorArg = requiredCtorArg;
- this.nullableCtorArg = nullableCtorArg;
- }
- }
-
// --> NESTED DOMAIN TYPE
static final String WITH_NESTED_DOMAIN_TYPE = "" + //
@@ -214,21 +165,6 @@ public class MappingMongoJsonSchemaCreatorUnitTests {
VariousFieldTypes nested;
}
- static final String WITH_NESTED_DOMAIN_TYPE_HAVING_REQUIRED_CTOR = "" + //
- "{" + //
- " 'type' : 'object'," + //
- " 'properties' : {" + //
- " '_id' : { 'type' : 'object' }," + //
- " 'nested' : " + REQUIRED_ARGS_CTOR + //
- " }" + //
- "}";
-
- static class WithNestedDomainTypeHavingRequiredCtor {
-
- String id;
- RequiredArgsCtor nested;
- }
-
// --> EXPLICIT MONGO_ID MAPPING
final String WITH_EXPLICIT_MONGO_ID_TYPE_MAPPING = "" + //
diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc
index bff1c7aa1..56d296206 100644
--- a/src/main/asciidoc/new-features.adoc
+++ b/src/main/asciidoc/new-features.adoc
@@ -13,7 +13,7 @@
* Changed behavior of `Reactive/MongoOperations#count` now limiting the range to count matches within by passing on _offset_ & _limit_ to the server.
* Kotlin extension methods accepting `KClass` are deprecated now in favor of `reified` methods.
* Support of array filters in `Update` operations.
-* <> from domain types.
+* <> from domain types.
[[new-features.2-1-0]]
== What's New in Spring Data MongoDB 2.1
diff --git a/src/main/asciidoc/reference/mongo-custom-conversions.adoc b/src/main/asciidoc/reference/mongo-custom-conversions.adoc
index 90d6be1aa..c823e6a81 100644
--- a/src/main/asciidoc/reference/mongo-custom-conversions.adoc
+++ b/src/main/asciidoc/reference/mongo-custom-conversions.adoc
@@ -2,7 +2,7 @@
== Custom Conversions - Overriding Default Mapping
The most trivial way of influencing the the mapping result is by specifying the desired native MongoDB target type via the
-`@Field` annotation. This allows to work with non mongoDB types like `BigDecimal` in the domain model while persisting
+`@Field` annotation. This allows to work with non MongoDB types like `BigDecimal` in the domain model while persisting
values in native `org.bson.types.Decimal128` format.
.Explicit target type mapping
diff --git a/src/main/asciidoc/reference/mongo-json-schema.adoc b/src/main/asciidoc/reference/mongo-json-schema.adoc
index e53d63b3e..2f1bcf840 100644
--- a/src/main/asciidoc/reference/mongo-json-schema.adoc
+++ b/src/main/asciidoc/reference/mongo-json-schema.adoc
@@ -87,15 +87,14 @@ template.createCollection(Person.class, CollectionOptions.empty().schema(schema)
====
[[mongo.jsonSchema.generated]]
-==== Generating the Schema
+==== Generating a Schema
-Setting up a schema can be a time consuming task and we encourage everyone who decides to do so, to really take the time
-it takes. It's important, schema changes can be hard. However there might be times when one does not want to balked
-with it, and that is where the `JsonSchemaCreator` comes into play.
+Setting up a schema can be a time consuming task and we encourage everyone who decides to do so, to really take the time it takes.
+It's important, schema changes can be hard.
+However, there might be times when one does not want to balked with it, and that is where `JsonSchemaCreator` comes into play.
-The `JsonSchemaCreator` and its default implementation generate the `MongoJsonSchema` out of the domain types metadata provided
-by the mapping infrastructure. This means that <> as well as potential <>
-are considered.
+`JsonSchemaCreator` and its default implementation generates a `MongoJsonSchema` out of domain types metadata provided by the mapping infrastructure.
+This means, that <> as well as potential <> are considered.
.Generate Json Schema from domain type
====
@@ -103,25 +102,24 @@ are considered.
----
public class Person {
- private final String firstname; <1>
- private final @Nullable String lastname; <2>
- private int age; <3>
- private Species species; <4>
- private Address address; <5>
- private @Field(fieldType=SCRIPT) String theForce; <6>
- private @Transient Boolean useTheForce; <7>
+ private final String firstname; <1>
+ private final int age; <2>
+ private Species species; <3>
+ private Address address; <4>
+ private @Field(fieldType=SCRIPT) String theForce; <5>
+ private @Transient Boolean useTheForce; <6>
- public Person(String firstname, @Nullable String lastname) { <1> <2>
+ public Person(String firstname, int age) { <1> <2>
this.firstname = firstname;
- this.lastname = lastname;
+ this.age = age;
}
// gettter / setter omitted
}
-MongoJsonSchema schema = schemaCreator.jsonSchemaCreator(mongoOperations.getConverter())
- .createSchemaFor(DomainType.class);
+MongoJsonSchema schema = MongoJsonSchemaCreator.create(mongoOperations.getConverter())
+ .createSchemaFor(Person.class);
template.createCollection(Person.class, CollectionOptions.empty().schema(schema));
----
@@ -130,38 +128,36 @@ template.createCollection(Person.class, CollectionOptions.empty().schema(schema)
----
{
'type' : 'object',
- 'required' : ['firstname', 'age'], <1> <3>
+ 'required' : ['age'], <2>
'properties' : {
- 'firstname' : { 'type' : 'string' }, <1>
- 'lastname' : { 'type' : 'string' }, <2>
- 'age' : { 'bsonType' : 'int' } <3>
- 'species' : { <4>
+ 'firstname' : { 'type' : 'string' }, <1>
+ 'age' : { 'bsonType' : 'int' } <2>
+ 'species' : { <3>
'type' : 'string',
'enum' : ['HUMAN', 'WOOKIE', 'UNKNOWN']
}
- 'address' : { <5>
+ 'address' : { <4>
'type' : 'object'
'properties' : {
'postCode' : { 'type': 'string' }
}
},
- 'theForce' : { 'type' : 'javascript'} <6>
+ 'theForce' : { 'type' : 'javascript'} <5>
}
}
----
-<1> Required property as **not** `@Nullable` and used in the constructor.
-<2> Optional property though used in the constructor it is still `@Nullable`.
-<3> Primitive types are considered required properties.
-<4> Enums are restricted to possible values.
-<5> Object type properties get are inspected themselfes.
-<6> `String` type property that is truned into `Code` by the mapping.
-<7> `@Transient` properties are left out when generating the schema.
+<1> Simple object properties are consideres regular properties.
+<2> Primitive types are considered required properties
+<3> Enums are restricted to possible values.
+<4> Object type properties are inspected and represented as nested documents.
+<5> `String` type property that is converted to `Code` by the converter.
+<6> `@Transient` properties are omitted when generating the schema.
====
NOTE: `_id` properties using types that can be converted into `ObjectId` like `String` are mapped to `{ type : 'object' }`
unless there is more specific information available via the `@MongoId` annotation.
-[cols="3,1,6", options="header"]
+[cols="2,2,6", options="header"]
.Sepcial Schema Generation rules
|===
| Java
@@ -169,33 +165,33 @@ unless there is more specific information available via the `@MongoId` annotatio
| Notes
| `Object`
-| type : object
+| `type : object`
| with `properties` if metadata available.
| `Collection`
-| type : array
+| `type : array`
| -
| `Map`
-| type : object
+| `type : object`
| -
| `Enum`
-| type : string
+| `type : string`
| with `enum` property holding the possible enumeration values.
| `array`
-| type : array
+| `type : array`
| simple type array unless it's a `byte[]`
| `byte[]`
-| bsonType : binData
+| `bsonType : binData`
| -
|===
[[mongo.jsonSchema.query]]
-==== Query a collection for matching Json Schema
+==== Query a collection for matching JSON Schema
You can use a schema to query any collection for documents that match a given structure defined by a JSON schema, as the following example shows:
@@ -210,7 +206,7 @@ template.find(query(matchingDocumentStructure(schema)), Person.class);
====
[[mongo.jsonSchema.types]]
-==== Json Schema Types
+==== JSON Schema Types
The following table shows the supported JSON schema types: