|
|
|
@ -53,7 +53,9 @@ import org.springframework.core.env.EnvironmentCapable; |
|
|
|
import org.springframework.core.env.StandardEnvironment; |
|
|
|
import org.springframework.core.env.StandardEnvironment; |
|
|
|
import org.springframework.data.annotation.Reference; |
|
|
|
import org.springframework.data.annotation.Reference; |
|
|
|
import org.springframework.data.convert.CustomConversions; |
|
|
|
import org.springframework.data.convert.CustomConversions; |
|
|
|
|
|
|
|
import org.springframework.data.convert.PropertyValueConverter; |
|
|
|
import org.springframework.data.convert.TypeMapper; |
|
|
|
import org.springframework.data.convert.TypeMapper; |
|
|
|
|
|
|
|
import org.springframework.data.convert.ValueConversionContext; |
|
|
|
import org.springframework.data.mapping.Association; |
|
|
|
import org.springframework.data.mapping.Association; |
|
|
|
import org.springframework.data.mapping.InstanceCreatorMetadata; |
|
|
|
import org.springframework.data.mapping.InstanceCreatorMetadata; |
|
|
|
import org.springframework.data.mapping.MappingException; |
|
|
|
import org.springframework.data.mapping.MappingException; |
|
|
|
@ -176,12 +178,11 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
this.idMapper = new QueryMapper(this); |
|
|
|
this.idMapper = new QueryMapper(this); |
|
|
|
|
|
|
|
|
|
|
|
this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE); |
|
|
|
this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE); |
|
|
|
this.dbRefProxyHandler = new DefaultDbRefProxyHandler(mappingContext, |
|
|
|
this.dbRefProxyHandler = new DefaultDbRefProxyHandler(mappingContext, (prop, bson, evaluator, path) -> { |
|
|
|
(prop, bson, evaluator, path) -> { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConversionContext context = getConversionContext(path); |
|
|
|
ConversionContext context = getConversionContext(path); |
|
|
|
return MappingMongoConverter.this.getValueInternal(context, prop, bson, evaluator); |
|
|
|
return MappingMongoConverter.this.getValueInternal(context, prop, bson, evaluator); |
|
|
|
}, expressionEvaluatorFactory::create); |
|
|
|
}, expressionEvaluatorFactory::create); |
|
|
|
|
|
|
|
|
|
|
|
this.referenceLookupDelegate = new ReferenceLookupDelegate(mappingContext, spELContext); |
|
|
|
this.referenceLookupDelegate = new ReferenceLookupDelegate(mappingContext, spELContext); |
|
|
|
this.documentPointerFactory = new DocumentPointerFactory(conversionService, mappingContext); |
|
|
|
this.documentPointerFactory = new DocumentPointerFactory(conversionService, mappingContext); |
|
|
|
@ -903,7 +904,10 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
Object value = accessor.getProperty(prop); |
|
|
|
Object value = accessor.getProperty(prop); |
|
|
|
|
|
|
|
|
|
|
|
if (value == null) { |
|
|
|
if (value == null) { |
|
|
|
if (prop.writeNullValues()) { |
|
|
|
|
|
|
|
|
|
|
|
if (conversions.hasValueConverter(prop)) { |
|
|
|
|
|
|
|
dbObjectAccessor.put(prop, applyPropertyConversion(null, prop, accessor)); |
|
|
|
|
|
|
|
} else { |
|
|
|
dbObjectAccessor.put(prop, null); |
|
|
|
dbObjectAccessor.put(prop, null); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (!conversions.isSimpleType(value.getClass())) { |
|
|
|
} else if (!conversions.isSimpleType(value.getClass())) { |
|
|
|
@ -941,14 +945,7 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
TypeInformation<?> type = prop.getTypeInformation(); |
|
|
|
TypeInformation<?> type = prop.getTypeInformation(); |
|
|
|
|
|
|
|
|
|
|
|
if (conversions.hasValueConverter(prop)) { |
|
|
|
if (conversions.hasValueConverter(prop)) { |
|
|
|
accessor.put(prop, conversions.getPropertyValueConversions().getValueConverter(prop).write(obj, |
|
|
|
accessor.put(prop, applyPropertyConversion(obj, prop, persistentPropertyAccessor)); |
|
|
|
new MongoConversionContext(new PropertyValueProvider<>() { |
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public <T> T getPropertyValue(MongoPersistentProperty property) { |
|
|
|
|
|
|
|
return (T) persistentPropertyAccessor.getProperty(property); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, prop, this, spELContext))); |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -987,8 +984,8 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
dbRefObj = proxy.toDBRef(); |
|
|
|
dbRefObj = proxy.toDBRef(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(obj !=null && conversions.hasCustomWriteTarget(obj.getClass())) { |
|
|
|
if (obj != null && conversions.hasCustomWriteTarget(obj.getClass())) { |
|
|
|
accessor.withCheckFieldMapping(true).put(prop, doConvert(obj, conversions.getCustomWriteTarget(obj.getClass()).get())); |
|
|
|
accessor.put(prop, doConvert(obj, conversions.getCustomWriteTarget(obj.getClass()).get())); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1290,17 +1287,10 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersistentProperty property, |
|
|
|
private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersistentProperty property, |
|
|
|
PersistentPropertyAccessor<?> persistentPropertyAccessor) { |
|
|
|
PersistentPropertyAccessor<?> persistentPropertyAccessor) { |
|
|
|
|
|
|
|
|
|
|
|
DocumentAccessor accessor = new DocumentAccessor(bson).withCheckFieldMapping(true); |
|
|
|
DocumentAccessor accessor = new DocumentAccessor(bson); |
|
|
|
|
|
|
|
|
|
|
|
if (conversions.hasValueConverter(property)) { |
|
|
|
if (conversions.hasValueConverter(property)) { |
|
|
|
accessor.put(property, conversions.getPropertyValueConversions().getValueConverter(property).write(value, |
|
|
|
accessor.put(property, applyPropertyConversion(value, property, persistentPropertyAccessor)); |
|
|
|
new MongoConversionContext(new PropertyValueProvider<>() { |
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public <T> T getPropertyValue(MongoPersistentProperty property) { |
|
|
|
|
|
|
|
return (T) persistentPropertyAccessor.getProperty(property); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, property, this, spELContext))); |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1308,6 +1298,23 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
property.hasExplicitWriteTarget() ? property.getFieldType() : Object.class)); |
|
|
|
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> T getPropertyValue(MongoPersistentProperty property) { |
|
|
|
|
|
|
|
return (T) persistentPropertyAccessor.getProperty(property); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, property, this, spELContext); |
|
|
|
|
|
|
|
PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter = conversions |
|
|
|
|
|
|
|
.getPropertyValueConversions().getValueConverter(property); |
|
|
|
|
|
|
|
return value != null ? valueConverter.write(value, context) : valueConverter.writeNull(context); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Checks whether we have a custom conversion registered for the given value into an arbitrary simple Mongo type. |
|
|
|
* Checks whether we have a custom conversion registered for the given value into an arbitrary simple Mongo type. |
|
|
|
* Returns the converted value if so. If not, we perform special enum handling or simply return the value as is. |
|
|
|
* Returns the converted value if so. If not, we perform special enum handling or simply return the value as is. |
|
|
|
@ -1948,14 +1955,18 @@ public class MappingMongoConverter extends AbstractMongoConverter |
|
|
|
String expression = property.getSpelExpression(); |
|
|
|
String expression = property.getSpelExpression(); |
|
|
|
Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property); |
|
|
|
Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property); |
|
|
|
|
|
|
|
|
|
|
|
if (value == null) { |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CustomConversions conversions = context.getCustomConversions(); |
|
|
|
CustomConversions conversions = context.getCustomConversions(); |
|
|
|
if (conversions.hasValueConverter(property)) { |
|
|
|
if (conversions.hasValueConverter(property)) { |
|
|
|
return (T) conversions.getPropertyValueConversions().getValueConverter(property).read(value, |
|
|
|
MongoConversionContext conversionContext = new MongoConversionContext(this, property, |
|
|
|
new MongoConversionContext(this, property, context.getSourceConverter(), spELContext)); |
|
|
|
context.getSourceConverter(), spELContext); |
|
|
|
|
|
|
|
PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter = conversions |
|
|
|
|
|
|
|
.getPropertyValueConversions().getValueConverter(property); |
|
|
|
|
|
|
|
return (T) (value != null ? valueConverter.read(value, conversionContext) |
|
|
|
|
|
|
|
: valueConverter.readNull(conversionContext)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (value == null) { |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ConversionContext contextToUse = context.forProperty(property); |
|
|
|
ConversionContext contextToUse = context.forProperty(property); |
|
|
|
|