15
15
*/
16
16
package org .springframework .data .mongodb .core .convert ;
17
17
18
- import java .util .*;
18
+ import java .util .AbstractMap ;
19
+ import java .util .ArrayList ;
20
+ import java .util .Arrays ;
21
+ import java .util .Collection ;
22
+ import java .util .Iterator ;
23
+ import java .util .LinkedHashMap ;
24
+ import java .util .List ;
25
+ import java .util .Map ;
19
26
import java .util .Map .Entry ;
27
+ import java .util .Optional ;
28
+ import java .util .Set ;
20
29
import java .util .regex .Matcher ;
21
30
import java .util .regex .Pattern ;
22
31
import java .util .stream .Collectors ;
27
36
import org .bson .Document ;
28
37
import org .bson .conversions .Bson ;
29
38
import org .bson .types .ObjectId ;
39
+
30
40
import org .springframework .core .convert .ConversionService ;
31
41
import org .springframework .core .convert .converter .Converter ;
32
42
import org .springframework .data .annotation .Reference ;
@@ -496,7 +506,7 @@ protected boolean isAssociationConversionNecessary(Field documentField, @Nullabl
496
506
497
507
Assert .notNull (documentField , "Document field must not be null" );
498
508
499
- if (value == null ) {
509
+ if (value == null || documentField . getProperty () == null ) {
500
510
return false ;
501
511
}
502
512
@@ -552,10 +562,6 @@ protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersisten
552
562
return getMappedObject ((Document ) source , entity );
553
563
}
554
564
555
- if (source instanceof BasicDBList ) {
556
- return delegateConvertToMongoType (source , entity );
557
- }
558
-
559
565
if (isDBObject (source )) {
560
566
return getMappedObject ((BasicDBObject ) source , entity );
561
567
}
@@ -564,20 +570,20 @@ protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersisten
564
570
return source ;
565
571
}
566
572
567
- if (source instanceof Map <?,?> sourceMap ) {
573
+ if (source instanceof Map <?, ?> sourceMap ) {
568
574
569
575
Map <String , Object > map = new LinkedHashMap <>(sourceMap .size (), 1F );
570
576
571
- sourceMap .entrySet (). forEach ( it -> {
577
+ for ( Entry <?, ?> entry : sourceMap .entrySet ()) {
572
578
573
- String key = ObjectUtils .nullSafeToString (converter .convertToMongoType (it .getKey ()));
579
+ String key = ObjectUtils .nullSafeToString (converter .convertToMongoType (entry .getKey ()));
574
580
575
- if (it .getValue () instanceof Document document ) {
581
+ if (entry .getValue () instanceof Document document ) {
576
582
map .put (key , getMappedObject (document , entity ));
577
583
} else {
578
- map .put (key , delegateConvertToMongoType (it .getValue (), entity ));
584
+ map .put (key , delegateConvertToMongoType (entry .getValue (), entity ));
579
585
}
580
- });
586
+ }
581
587
582
588
return map ;
583
589
}
@@ -603,6 +609,7 @@ protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersis
603
609
return converter .convertToMongoType (source , entity == null ? null : entity .getTypeInformation ());
604
610
}
605
611
612
+ @ Nullable
606
613
protected Object convertAssociation (Object source , Field field ) {
607
614
Object value = convertAssociation (source , field .getProperty ());
608
615
if (value != null && field .isIdField () && field .getFieldType () != value .getClass ()) {
@@ -627,8 +634,7 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
627
634
628
635
if (source instanceof DBRef ref ) {
629
636
630
- Object id = convertId (ref .getId (),
631
- property != null && property .isIdProperty () ? property .getFieldType () : ObjectId .class );
637
+ Object id = convertId (ref .getId (), property .isIdProperty () ? property .getFieldType () : ObjectId .class );
632
638
633
639
if (StringUtils .hasText (ref .getDatabaseName ())) {
634
640
return new DBRef (ref .getDatabaseName (), ref .getCollectionName (), id );
@@ -645,9 +651,8 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
645
651
return result ;
646
652
}
647
653
648
- if (property .isMap ()) {
654
+ if (property .isMap () && source instanceof Document dbObject ) {
649
655
Document result = new Document ();
650
- Document dbObject = (Document ) source ;
651
656
for (String key : dbObject .keySet ()) {
652
657
result .put (key , createReferenceFor (dbObject .get (key ), property ));
653
658
}
@@ -661,19 +666,26 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
661
666
private Object convertValue (Field documentField , Object sourceValue , Object value ,
662
667
PropertyValueConverter <Object , Object , ValueConversionContext <MongoPersistentProperty >> valueConverter ) {
663
668
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 );
669
+ MongoPersistentProperty property = documentField .getProperty ();
670
+ MongoConversionContext conversionContext = new MongoConversionContext (NoPropertyPropertyValueProvider .INSTANCE ,
671
+ property , converter );
670
672
671
673
/* 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
+ if (property != null && !property .isCollectionLike () && sourceValue instanceof Collection <?> collection ) {
675
+
676
+ if (collection .isEmpty ()) {
677
+ return collection ;
678
+ }
679
+
680
+ List <Object > converted = new ArrayList <>(collection .size ());
681
+ for (Object o : collection ) {
682
+ converted .add (valueConverter .write (o , conversionContext ));
683
+ }
684
+
685
+ return converted ;
674
686
}
675
687
676
- if (!documentField .getProperty ().isMap () && sourceValue instanceof Document document ) {
688
+ if (property != null && !documentField .getProperty ().isMap () && sourceValue instanceof Document document ) {
677
689
678
690
return BsonUtils .mapValues (document , (key , val ) -> {
679
691
if (isKeyword (key )) {
@@ -687,6 +699,7 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
687
699
}
688
700
689
701
@ Nullable
702
+ @ SuppressWarnings ("unchecked" )
690
703
private Object convertIdField (Field documentField , Object source ) {
691
704
692
705
Object value = source ;
@@ -714,8 +727,8 @@ private Object convertIdField(Field documentField, Object source) {
714
727
} else {
715
728
return getMappedObject (resultDbo , Optional .empty ());
716
729
}
717
- return resultDbo ;
718
730
731
+ return resultDbo ;
719
732
}
720
733
721
734
/**
@@ -1454,15 +1467,13 @@ static class KeyMapper {
1454
1467
1455
1468
private final Iterator <String > iterator ;
1456
1469
private int currentIndex ;
1457
- private String currentPropertyRoot ;
1458
1470
private final List <String > pathParts ;
1459
1471
1460
1472
public KeyMapper (String key ,
1461
1473
MappingContext <? extends MongoPersistentEntity <?>, MongoPersistentProperty > mappingContext ) {
1462
1474
1463
1475
this .pathParts = Arrays .asList (key .split ("\\ ." ));
1464
1476
this .iterator = pathParts .iterator ();
1465
- this .currentPropertyRoot = iterator .next ();
1466
1477
this .currentIndex = 0 ;
1467
1478
}
1468
1479
@@ -1578,4 +1589,14 @@ public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentPropert
1578
1589
public MongoConverter getConverter () {
1579
1590
return converter ;
1580
1591
}
1592
+
1593
+ private enum NoPropertyPropertyValueProvider implements PropertyValueProvider <MongoPersistentProperty > {
1594
+
1595
+ INSTANCE ;
1596
+
1597
+ @ Override
1598
+ public <T > T getPropertyValue (MongoPersistentProperty property ) {
1599
+ throw new IllegalStateException ("No enclosing property source available" );
1600
+ }
1601
+ }
1581
1602
}
0 commit comments