@@ -449,65 +449,14 @@ protected Object getMappedValue(Field documentField, Object sourceValue) {
449449 if (documentField .getProperty () != null
450450 && converter .getCustomConversions ().hasValueConverter (documentField .getProperty ())) {
451451
452- MongoConversionContext conversionContext = new MongoConversionContext (new PropertyValueProvider <>() {
453- @ Override
454- public <T > T getPropertyValue (MongoPersistentProperty property ) {
455- throw new IllegalStateException ("No enclosing property available" );
456- }
457- }, documentField .getProperty (), converter );
458452 PropertyValueConverter <Object , Object , ValueConversionContext <MongoPersistentProperty >> valueConverter = converter
459453 .getCustomConversions ().getPropertyValueConversions ().getValueConverter (documentField .getProperty ());
460454
461- /* might be an $in clause with multiple entries */
462- if (!documentField .getProperty ().isCollectionLike () && sourceValue instanceof Collection <?> collection ) {
463- return collection .stream ().map (it -> valueConverter .write (it , conversionContext )).collect (Collectors .toList ());
464- }
465-
466- return valueConverter .write (value , conversionContext );
455+ return convertValue (documentField , sourceValue , value , valueConverter );
467456 }
468457
469458 if (documentField .isIdField () && !documentField .isAssociation ()) {
470-
471- if (isDBObject (value )) {
472- DBObject valueDbo = (DBObject ) value ;
473- Document resultDbo = new Document (valueDbo .toMap ());
474-
475- if (valueDbo .containsField ("$in" ) || valueDbo .containsField ("$nin" )) {
476- String inKey = valueDbo .containsField ("$in" ) ? "$in" : "$nin" ;
477- List <Object > ids = new ArrayList <>();
478- for (Object id : (Iterable <?>) valueDbo .get (inKey )) {
479- ids .add (convertId (id , getIdTypeForField (documentField )));
480- }
481- resultDbo .put (inKey , ids );
482- } else if (valueDbo .containsField ("$ne" )) {
483- resultDbo .put ("$ne" , convertId (valueDbo .get ("$ne" ), getIdTypeForField (documentField )));
484- } else {
485- return getMappedObject (resultDbo , Optional .empty ());
486- }
487- return resultDbo ;
488- }
489-
490- else if (isDocument (value )) {
491- Document valueDbo = (Document ) value ;
492- Document resultDbo = new Document (valueDbo );
493-
494- if (valueDbo .containsKey ("$in" ) || valueDbo .containsKey ("$nin" )) {
495- String inKey = valueDbo .containsKey ("$in" ) ? "$in" : "$nin" ;
496- List <Object > ids = new ArrayList <>();
497- for (Object id : (Iterable <?>) valueDbo .get (inKey )) {
498- ids .add (convertId (id , getIdTypeForField (documentField )));
499- }
500- resultDbo .put (inKey , ids );
501- } else if (valueDbo .containsKey ("$ne" )) {
502- resultDbo .put ("$ne" , convertId (valueDbo .get ("$ne" ), getIdTypeForField (documentField )));
503- } else {
504- return getMappedObject (resultDbo , Optional .empty ());
505- }
506- return resultDbo ;
507-
508- } else {
509- return convertId (value , getIdTypeForField (documentField ));
510- }
459+ return convertIdField (documentField , value );
511460 }
512461
513462 if (value == null ) {
@@ -708,6 +657,67 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
708657 return createReferenceFor (source , property );
709658 }
710659
660+ @ Nullable
661+ private Object convertValue (Field documentField , Object sourceValue , Object value ,
662+ PropertyValueConverter <Object , Object , ValueConversionContext <MongoPersistentProperty >> valueConverter ) {
663+
664+ MongoConversionContext conversionContext = new MongoConversionContext (new PropertyValueProvider <>() {
665+ @ Override
666+ public <T > T getPropertyValue (MongoPersistentProperty property ) {
667+ throw new IllegalStateException ("No enclosing property available" );
668+ }
669+ }, documentField .getProperty (), converter );
670+
671+ /* might be an $in clause with multiple entries */
672+ if (!documentField .getProperty ().isCollectionLike () && sourceValue instanceof Collection <?> collection ) {
673+ return collection .stream ().map (it -> valueConverter .write (it , conversionContext )).collect (Collectors .toList ());
674+ }
675+
676+ if (!documentField .getProperty ().isMap () && sourceValue instanceof Document document ) {
677+
678+ return BsonUtils .mapValues (document , (key , val ) -> {
679+ if (isKeyword (key )) {
680+ return getMappedValue (documentField , val );
681+ }
682+ return val ;
683+ });
684+ }
685+
686+ return valueConverter .write (value , conversionContext );
687+ }
688+
689+ @ Nullable
690+ private Object convertIdField (Field documentField , Object source ) {
691+
692+ Object value = source ;
693+ if (isDBObject (source )) {
694+ DBObject valueDbo = (DBObject ) source ;
695+ value = new Document (valueDbo .toMap ());
696+ }
697+
698+ if (!isDocument (value )) {
699+ return convertId (value , getIdTypeForField (documentField ));
700+ }
701+
702+ Document valueDbo = (Document ) value ;
703+ Document resultDbo = new Document (valueDbo );
704+
705+ if (valueDbo .containsKey ("$in" ) || valueDbo .containsKey ("$nin" )) {
706+ String inKey = valueDbo .containsKey ("$in" ) ? "$in" : "$nin" ;
707+ List <Object > ids = new ArrayList <>();
708+ for (Object id : (Iterable <?>) valueDbo .get (inKey )) {
709+ ids .add (convertId (id , getIdTypeForField (documentField )));
710+ }
711+ resultDbo .put (inKey , ids );
712+ } else if (valueDbo .containsKey ("$ne" )) {
713+ resultDbo .put ("$ne" , convertId (valueDbo .get ("$ne" ), getIdTypeForField (documentField )));
714+ } else {
715+ return getMappedObject (resultDbo , Optional .empty ());
716+ }
717+ return resultDbo ;
718+
719+ }
720+
711721 /**
712722 * Checks whether the given value is a {@link Document}.
713723 *
0 commit comments