|
53 | 53 | import org.springframework.core.env.StandardEnvironment;
|
54 | 54 | import org.springframework.data.annotation.Reference;
|
55 | 55 | import org.springframework.data.convert.CustomConversions;
|
| 56 | +import org.springframework.data.convert.PropertyValueConverter; |
56 | 57 | import org.springframework.data.convert.TypeMapper;
|
| 58 | +import org.springframework.data.convert.ValueConversionContext; |
57 | 59 | import org.springframework.data.mapping.Association;
|
58 | 60 | import org.springframework.data.mapping.InstanceCreatorMetadata;
|
59 | 61 | import org.springframework.data.mapping.MappingException;
|
@@ -176,12 +178,11 @@ public MappingMongoConverter(DbRefResolver dbRefResolver,
|
176 | 178 | this.idMapper = new QueryMapper(this);
|
177 | 179 |
|
178 | 180 | this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE);
|
179 |
| - this.dbRefProxyHandler = new DefaultDbRefProxyHandler(mappingContext, |
180 |
| - (prop, bson, evaluator, path) -> { |
| 181 | + this.dbRefProxyHandler = new DefaultDbRefProxyHandler(mappingContext, (prop, bson, evaluator, path) -> { |
181 | 182 |
|
182 |
| - ConversionContext context = getConversionContext(path); |
183 |
| - return MappingMongoConverter.this.getValueInternal(context, prop, bson, evaluator); |
184 |
| - }, expressionEvaluatorFactory::create); |
| 183 | + ConversionContext context = getConversionContext(path); |
| 184 | + return MappingMongoConverter.this.getValueInternal(context, prop, bson, evaluator); |
| 185 | + }, expressionEvaluatorFactory::create); |
185 | 186 |
|
186 | 187 | this.referenceLookupDelegate = new ReferenceLookupDelegate(mappingContext, spELContext);
|
187 | 188 | this.documentPointerFactory = new DocumentPointerFactory(conversionService, mappingContext);
|
@@ -903,7 +904,10 @@ private void writeProperties(Bson bson, MongoPersistentEntity<?> entity, Persist
|
903 | 904 | Object value = accessor.getProperty(prop);
|
904 | 905 |
|
905 | 906 | if (value == null) {
|
906 |
| - if (prop.writeNullValues()) { |
| 907 | + |
| 908 | + if (conversions.hasValueConverter(prop)) { |
| 909 | + dbObjectAccessor.put(prop, applyPropertyConversion(null, prop, accessor)); |
| 910 | + } else { |
907 | 911 | dbObjectAccessor.put(prop, null);
|
908 | 912 | }
|
909 | 913 | } else if (!conversions.isSimpleType(value.getClass())) {
|
@@ -941,14 +945,7 @@ protected void writePropertyInternal(@Nullable Object obj, DocumentAccessor acce
|
941 | 945 | TypeInformation<?> type = prop.getTypeInformation();
|
942 | 946 |
|
943 | 947 | if (conversions.hasValueConverter(prop)) {
|
944 |
| - accessor.put(prop, conversions.getPropertyValueConversions().getValueConverter(prop).write(obj, |
945 |
| - new MongoConversionContext(new PropertyValueProvider<>() { |
946 |
| - @Nullable |
947 |
| - @Override |
948 |
| - public <T> T getPropertyValue(MongoPersistentProperty property) { |
949 |
| - return (T) persistentPropertyAccessor.getProperty(property); |
950 |
| - } |
951 |
| - }, prop, this, spELContext))); |
| 948 | + accessor.put(prop, applyPropertyConversion(obj, prop, persistentPropertyAccessor)); |
952 | 949 | return;
|
953 | 950 | }
|
954 | 951 |
|
@@ -987,8 +984,8 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
|
987 | 984 | dbRefObj = proxy.toDBRef();
|
988 | 985 | }
|
989 | 986 |
|
990 |
| - if(obj !=null && conversions.hasCustomWriteTarget(obj.getClass())) { |
991 |
| - accessor.withCheckFieldMapping(true).put(prop, doConvert(obj, conversions.getCustomWriteTarget(obj.getClass()).get())); |
| 987 | + if (obj != null && conversions.hasCustomWriteTarget(obj.getClass())) { |
| 988 | + accessor.put(prop, doConvert(obj, conversions.getCustomWriteTarget(obj.getClass()).get())); |
992 | 989 | return;
|
993 | 990 | }
|
994 | 991 |
|
@@ -1290,24 +1287,34 @@ private void writeSimpleInternal(@Nullable Object value, Bson bson, String key)
|
1290 | 1287 | private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersistentProperty property,
|
1291 | 1288 | PersistentPropertyAccessor<?> persistentPropertyAccessor) {
|
1292 | 1289 |
|
1293 |
| - DocumentAccessor accessor = new DocumentAccessor(bson).withCheckFieldMapping(true); |
| 1290 | + DocumentAccessor accessor = new DocumentAccessor(bson); |
1294 | 1291 |
|
1295 | 1292 | if (conversions.hasValueConverter(property)) {
|
1296 |
| - accessor.put(property, conversions.getPropertyValueConversions().getValueConverter(property).write(value, |
1297 |
| - new MongoConversionContext(new PropertyValueProvider<>() { |
1298 |
| - @Nullable |
1299 |
| - @Override |
1300 |
| - public <T> T getPropertyValue(MongoPersistentProperty property) { |
1301 |
| - return (T) persistentPropertyAccessor.getProperty(property); |
1302 |
| - } |
1303 |
| - }, property, this, spELContext))); |
| 1293 | + accessor.put(property, applyPropertyConversion(value, property, persistentPropertyAccessor)); |
1304 | 1294 | return;
|
1305 | 1295 | }
|
1306 | 1296 |
|
1307 | 1297 | accessor.put(property, getPotentiallyConvertedSimpleWrite(value,
|
1308 | 1298 | property.hasExplicitWriteTarget() ? property.getFieldType() : Object.class));
|
1309 | 1299 | }
|
1310 | 1300 |
|
| 1301 | + @Nullable |
| 1302 | + @SuppressWarnings("unchecked") |
| 1303 | + private Object applyPropertyConversion(@Nullable Object value, MongoPersistentProperty property, |
| 1304 | + PersistentPropertyAccessor<?> persistentPropertyAccessor) { |
| 1305 | + MongoConversionContext context = new MongoConversionContext(new PropertyValueProvider<>() { |
| 1306 | + |
| 1307 | + @Nullable |
| 1308 | + @Override |
| 1309 | + public <T> T getPropertyValue(MongoPersistentProperty property) { |
| 1310 | + return (T) persistentPropertyAccessor.getProperty(property); |
| 1311 | + } |
| 1312 | + }, property, this, spELContext); |
| 1313 | + PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter = conversions |
| 1314 | + .getPropertyValueConversions().getValueConverter(property); |
| 1315 | + return value != null ? valueConverter.write(value, context) : valueConverter.writeNull(context); |
| 1316 | + } |
| 1317 | + |
1311 | 1318 | /**
|
1312 | 1319 | * Checks whether we have a custom conversion registered for the given value into an arbitrary simple Mongo type.
|
1313 | 1320 | * 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 <T> T getPropertyValue(MongoPersistentProperty property) {
|
1948 | 1955 | String expression = property.getSpelExpression();
|
1949 | 1956 | Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property);
|
1950 | 1957 |
|
1951 |
| - if (value == null) { |
1952 |
| - return null; |
1953 |
| - } |
1954 |
| - |
1955 | 1958 | CustomConversions conversions = context.getCustomConversions();
|
1956 | 1959 | if (conversions.hasValueConverter(property)) {
|
1957 |
| - return (T) conversions.getPropertyValueConversions().getValueConverter(property).read(value, |
1958 |
| - new MongoConversionContext(this, property, context.getSourceConverter(), spELContext)); |
| 1960 | + MongoConversionContext conversionContext = new MongoConversionContext(this, property, |
| 1961 | + context.getSourceConverter(), spELContext); |
| 1962 | + PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter = conversions |
| 1963 | + .getPropertyValueConversions().getValueConverter(property); |
| 1964 | + return (T) (value != null ? valueConverter.read(value, conversionContext) |
| 1965 | + : valueConverter.readNull(conversionContext)); |
| 1966 | + } |
| 1967 | + |
| 1968 | + if (value == null) { |
| 1969 | + return null; |
1959 | 1970 | }
|
1960 | 1971 |
|
1961 | 1972 | ConversionContext contextToUse = context.forProperty(property);
|
|
0 commit comments