diff --git a/pom.xml b/pom.xml
index f785c3872d..3b683893a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4710-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index a3dc49f892..c6ec56d465 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4710-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index acdc13437d..5612e61282 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4710-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index fafe9c8793..c1a519c90c 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4710-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java
index bade3ab7fc..0bfdfee010 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java
@@ -92,6 +92,10 @@ public void put(MongoPersistentProperty prop, @Nullable Object value) {
Assert.notNull(prop, "MongoPersistentProperty must not be null");
+ if (value == null && !prop.writeNullValues()) {
+ return;
+ }
+
Iterator parts = Arrays.asList(prop.getMongoField().getName().parts()).iterator();
Bson document = this.document;
@@ -172,4 +176,5 @@ private static Document getOrCreateNestedDocument(String key, Bson source) {
return nested;
}
+
}
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 4e38ab25c5..8db67109e5 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
@@ -53,7 +53,9 @@
import org.springframework.core.env.StandardEnvironment;
import org.springframework.data.annotation.Reference;
import org.springframework.data.convert.CustomConversions;
+import org.springframework.data.convert.PropertyValueConverter;
import org.springframework.data.convert.TypeMapper;
+import org.springframework.data.convert.ValueConversionContext;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.InstanceCreatorMetadata;
import org.springframework.data.mapping.MappingException;
@@ -176,12 +178,11 @@ public MappingMongoConverter(DbRefResolver dbRefResolver,
this.idMapper = new QueryMapper(this);
this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE);
- this.dbRefProxyHandler = new DefaultDbRefProxyHandler(mappingContext,
- (prop, bson, evaluator, path) -> {
+ this.dbRefProxyHandler = new DefaultDbRefProxyHandler(mappingContext, (prop, bson, evaluator, path) -> {
- ConversionContext context = getConversionContext(path);
- return MappingMongoConverter.this.getValueInternal(context, prop, bson, evaluator);
- }, expressionEvaluatorFactory::create);
+ ConversionContext context = getConversionContext(path);
+ return MappingMongoConverter.this.getValueInternal(context, prop, bson, evaluator);
+ }, expressionEvaluatorFactory::create);
this.referenceLookupDelegate = new ReferenceLookupDelegate(mappingContext, spELContext);
this.documentPointerFactory = new DocumentPointerFactory(conversionService, mappingContext);
@@ -279,6 +280,7 @@ public void setCodecRegistryProvider(@Nullable CodecRegistryProvider codecRegist
this.codecRegistryProvider = codecRegistryProvider;
}
+ @Override
public MappingContext extends MongoPersistentEntity>, MongoPersistentProperty> getMappingContext() {
return mappingContext;
}
@@ -431,6 +433,7 @@ public Map getBean() {
}
}
+ @Override
public S read(Class clazz, Bson bson) {
return read(TypeInformation.of(clazz), bson);
}
@@ -728,6 +731,7 @@ private Object readUnwrapped(ConversionContext context, DocumentAccessor documen
return null;
}
+ @Override
public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringProperty) {
org.springframework.data.mongodb.core.mapping.DBRef annotation;
@@ -794,6 +798,7 @@ DocumentPointer> createDocumentPointer(Object source, @Nullable MongoPersisten
*
* @see org.springframework.data.mongodb.core.convert.MongoWriter#write(java.lang.Object, java.lang.Object)
*/
+ @Override
public void write(Object obj, Bson bson) {
if (null == obj) {
@@ -903,7 +908,10 @@ private void writeProperties(Bson bson, MongoPersistentEntity> entity, Persist
Object value = accessor.getProperty(prop);
if (value == null) {
- if (prop.writeNullValues()) {
+
+ if (conversions.hasValueConverter(prop)) {
+ dbObjectAccessor.put(prop, applyPropertyConversion(null, prop, accessor));
+ } else {
dbObjectAccessor.put(prop, null);
}
} else if (!conversions.isSimpleType(value.getClass())) {
@@ -929,6 +937,7 @@ private void writeAssociation(Association association,
writePropertyInternal(value, dbObjectAccessor, inverseProp, accessor);
}
+ // TODO: Documentaccessor is package-private
@SuppressWarnings({ "unchecked" })
protected void writePropertyInternal(@Nullable Object obj, DocumentAccessor accessor, MongoPersistentProperty prop,
PersistentPropertyAccessor> persistentPropertyAccessor) {
@@ -941,14 +950,7 @@ protected void writePropertyInternal(@Nullable Object obj, DocumentAccessor acce
TypeInformation> type = prop.getTypeInformation();
if (conversions.hasValueConverter(prop)) {
- accessor.put(prop, conversions.getPropertyValueConversions().getValueConverter(prop).write(obj,
- new MongoConversionContext(new PropertyValueProvider<>() {
- @Nullable
- @Override
- public T getPropertyValue(MongoPersistentProperty property) {
- return (T) persistentPropertyAccessor.getProperty(property);
- }
- }, prop, this, spELContext)));
+ accessor.put(prop, applyPropertyConversion(obj, prop, persistentPropertyAccessor));
return;
}
@@ -987,6 +989,11 @@ public T getPropertyValue(MongoPersistentProperty property) {
dbRefObj = proxy.toDBRef();
}
+ if (obj != null && conversions.hasCustomWriteTarget(obj.getClass())) {
+ accessor.put(prop, doConvert(obj, conversions.getCustomWriteTarget(obj.getClass()).get()));
+ return;
+ }
+
dbRefObj = dbRefObj != null ? dbRefObj : createDBRef(obj, prop);
accessor.put(prop, dbRefObj);
@@ -1284,17 +1291,11 @@ private void writeSimpleInternal(@Nullable Object value, Bson bson, String key)
private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersistentProperty property,
PersistentPropertyAccessor> persistentPropertyAccessor) {
+
DocumentAccessor accessor = new DocumentAccessor(bson);
if (conversions.hasValueConverter(property)) {
- accessor.put(property, conversions.getPropertyValueConversions().getValueConverter(property).write(value,
- new MongoConversionContext(new PropertyValueProvider<>() {
- @Nullable
- @Override
- public T getPropertyValue(MongoPersistentProperty property) {
- return (T) persistentPropertyAccessor.getProperty(property);
- }
- }, property, this, spELContext)));
+ accessor.put(property, applyPropertyConversion(value, property, persistentPropertyAccessor));
return;
}
@@ -1302,6 +1303,23 @@ public T getPropertyValue(MongoPersistentProperty property) {
property.hasExplicitWriteTarget() ? property.getFieldType() : Object.class));
}
+ @Nullable
+ @SuppressWarnings("unchecked")
+ private Object applyPropertyConversion(@Nullable Object value, MongoPersistentProperty property,
+ PersistentPropertyAccessor> persistentPropertyAccessor) {
+ MongoConversionContext context = new MongoConversionContext(new PropertyValueProvider<>() {
+
+ @Nullable
+ @Override
+ public T getPropertyValue(MongoPersistentProperty property) {
+ return (T) persistentPropertyAccessor.getProperty(property);
+ }
+ }, property, this, spELContext);
+ PropertyValueConverter