parts = Arrays.asList(prop.getMongoField().getName().parts()).iterator();
Bson document = this.document;
while (parts.hasNext()) {
@@ -135,7 +129,7 @@ public Object get(MongoPersistentProperty property) {
*/
@Nullable
public Object getRawId(MongoPersistentEntity> entity) {
- return entity.hasIdProperty() ? get(entity.getRequiredIdProperty()) : BsonUtils.get(document, "_id");
+ return entity.hasIdProperty() ? get(entity.getRequiredIdProperty()) : BsonUtils.get(document, FieldName.ID.name());
}
/**
@@ -153,8 +147,8 @@ public boolean hasValue(MongoPersistentProperty property) {
return BsonUtils.hasValue(document, getFieldName(property));
}
- String getFieldName(MongoPersistentProperty prop) {
- return prop.getFieldName();
+ FieldName getFieldName(MongoPersistentProperty prop) {
+ return prop.getMongoField().getName();
}
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java
index 3c2e2dc3fe..1b673740c1 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java
@@ -34,6 +34,7 @@
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.BeanWrapperPropertyAccessorFactory;
import org.springframework.data.mongodb.core.mapping.DocumentPointer;
+import org.springframework.data.mongodb.core.mapping.FieldName;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
@@ -232,7 +233,7 @@ Object updatePlaceholders(org.bson.Document source, org.bson.Document target,
attribute = attribute.substring(attribute.lastIndexOf('.') + 1);
}
- String fieldName = entry.getKey().equals("_id") ? "id" : entry.getKey();
+ String fieldName = entry.getKey().equals(FieldName.ID.name()) ? "id" : entry.getKey();
if (!fieldName.contains(".")) {
Object targetValue = propertyAccessor.getProperty(persistentEntity.getPersistentProperty(fieldName));
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 ec5d866461..2949bebba7 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
@@ -72,6 +72,7 @@
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.DocumentPointer;
+import org.springframework.data.mongodb.core.mapping.FieldName;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.PersistentPropertyTranslator;
@@ -230,8 +231,8 @@ public CustomConversions getCustomConversions() {
}
/**
- * Configure the characters dots potentially contained in a {@link Map} shall be replaced with. By default we don't do
- * any translation but rather reject a {@link Map} with keys containing dots causing the conversion for the entire
+ * Configure the characters dots potentially contained in a {@link Map} shall be replaced with. By default, we don't
+ * do any translation but rather reject a {@link Map} with keys containing dots causing the conversion for the entire
* object to fail. If further customization of the translation is needed, have a look at
* {@link #potentiallyEscapeMapKey(String)} as well as {@link #potentiallyUnescapeMapKey(String)}.
*
@@ -244,6 +245,16 @@ public void setMapKeyDotReplacement(@Nullable String mapKeyDotReplacement) {
this.mapKeyDotReplacement = mapKeyDotReplacement;
}
+ /**
+ * If {@link #preserveMapKeys(boolean) preserve} is set to {@literal true} the conversion will treat map keys containing {@literal .} (dot) characters as is.
+ *
+ * @since 4.2
+ * @see #setMapKeyDotReplacement(String)
+ */
+ public void preserveMapKeys(boolean preserve) {
+ setMapKeyDotReplacement(preserve ? "." : null);
+ }
+
/**
* Configure a {@link CodecRegistryProvider} that provides native MongoDB {@link org.bson.codecs.Codec codecs} for
* reading values.
@@ -345,8 +356,8 @@ private R doReadProjection(ConversionContext context, Bson bson, EntityProje
Predicates.negate(MongoPersistentProperty::hasExplicitFieldName));
DocumentAccessor documentAccessor = new DocumentAccessor(bson) {
@Override
- String getFieldName(MongoPersistentProperty prop) {
- return propertyTranslator.translate(prop).getFieldName();
+ FieldName getFieldName(MongoPersistentProperty prop) {
+ return propertyTranslator.translate(prop).getMongoField().getName();
}
};
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
index 7344697979..dd6224472b 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
@@ -51,6 +51,7 @@
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
+import org.springframework.data.mongodb.core.mapping.FieldName;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.util.Assert;
@@ -300,7 +301,7 @@ public NamedMongoScript convert(Document source) {
return null;
}
- String id = source.get("_id").toString();
+ String id = source.get(FieldName.ID.name()).toString();
Object rawValue = source.get("value");
return new NamedMongoScript(id, ((Code) rawValue).getCode());
@@ -320,7 +321,7 @@ public Document convert(NamedMongoScript source) {
Document document = new Document();
- document.put("_id", source.getName());
+ document.put(FieldName.ID.name(), source.getName());
document.put("value", new Code(source.getCode()));
return document;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java
index 69757b22e9..f93afcee85 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java
@@ -34,6 +34,7 @@
import org.springframework.data.domain.ExampleMatcher.StringMatcher;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
+import org.springframework.data.mongodb.core.mapping.FieldName;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.query.MongoRegexCreator;
@@ -278,7 +279,8 @@ private Set> getTypesToMatch(Example> example) {
}
private static boolean isEmptyIdProperty(Entry entry) {
- return entry.getKey().equals("_id") && (entry.getValue() == null || entry.getValue().equals(Optional.empty()));
+ return entry.getKey().equals(FieldName.ID.name())
+ && (entry.getValue() == null || entry.getValue().equals(Optional.empty()));
}
private static void applyStringMatcher(Map.Entry entry, StringMatcher stringMatcher,
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
index 06aee31afc..156108c563 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
@@ -47,6 +47,7 @@
import org.springframework.data.mongodb.core.aggregation.AggregationExpression;
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter.NestedDocument;
+import org.springframework.data.mongodb.core.mapping.FieldName;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty.PropertyToFieldNameConverter;
@@ -80,7 +81,7 @@ public class QueryMapper {
protected static final Log LOGGER = LogFactory.getLog(QueryMapper.class);
- private static final List DEFAULT_ID_NAMES = Arrays.asList("id", "_id");
+ private static final List DEFAULT_ID_NAMES = Arrays.asList("id", FieldName.ID.name());
private static final Document META_TEXT_SCORE = new Document("$meta", "textScore");
static final TypeInformation> NESTED_DOCUMENT = TypeInformation.of(NestedDocument.class);
@@ -168,6 +169,14 @@ public Document getMappedObject(Bson query, @Nullable MongoPersistentEntity> e
Entry entry = getMappedObjectForField(field, BsonUtils.get(query, key));
+ /*
+ * Note to future self:
+ * ----
+ * This could be the place to plug in a query rewrite mechanism that allows to transform comparison
+ * against field that has a dot in its name (like 'a.b') into an $expr so that { "a.b" : "some value" }
+ * eventually becomes { $expr : { $eq : [ { $getField : "a.b" }, "some value" ] } }
+ * ----
+ */
result.put(entry.getKey(), entry.getValue());
}
} catch (InvalidPersistentPropertyPath invalidPathException) {
@@ -358,7 +367,7 @@ protected Field createPropertyField(@Nullable MongoPersistentEntity> entity, S
return new Field(key);
}
- if (Field.ID_KEY.equals(key)) {
+ if (FieldName.ID.name().equals(key)) {
return new MetadataBackedField(key, entity, mappingContext, entity.getIdProperty());
}
@@ -378,8 +387,7 @@ protected Document getMappedKeyword(Keyword keyword, @Nullable MongoPersistentEn
if (keyword.isOrOrNor() || (keyword.hasIterableValue() && !keyword.isGeometry())) {
Iterable> conditions = keyword.getValue();
- List