7070import org .springframework .data .mongodb .core .mapping .event .AfterConvertEvent ;
7171import org .springframework .data .mongodb .core .mapping .event .AfterLoadEvent ;
7272import org .springframework .data .mongodb .core .mapping .event .MongoMappingEvent ;
73+ import org .springframework .data .mongodb .util .BsonUtils ;
7374import org .springframework .data .util .ClassTypeInformation ;
7475import org .springframework .data .util .TypeInformation ;
7576import org .springframework .lang .Nullable ;
@@ -270,17 +271,25 @@ public <S extends Object> S read(Class<S> clazz, final Bson bson) {
270271 }
271272
272273 protected <S extends Object > S read (TypeInformation <S > type , Bson bson ) {
273- return doRead (getConversionContext (ObjectPath .ROOT ), type , bson );
274+ return readDocument (getConversionContext (ObjectPath .ROOT ), bson , type );
274275 }
275276
277+ /**
278+ * Conversion method to materialize an object from a {@link Bson document}. Can be overridden by subclasses.
279+ *
280+ * @param context must not be {@literal null}
281+ * @param bson must not be {@literal null}
282+ * @param typeHint the {@link TypeInformation} to be used to unmarshall this {@link Document}.
283+ * @return the converted object, will never be {@literal null}.
284+ * @since 3.2
285+ */
276286 @ SuppressWarnings ("unchecked" )
277- private <S extends Object > S doRead (ConversionContext context , TypeInformation <S > type , Bson bson ) {
278-
279- Assert .notNull (bson , "Bson must not be null!" );
287+ protected <S extends Object > S readDocument (ConversionContext context , Bson bson ,
288+ TypeInformation <? extends S > typeHint ) {
280289
281- // TODO: Cleanup duplication
282- TypeInformation <? extends S > typeToUse = typeMapper .readType (bson , type );
283- Class <? extends S > rawType = typeToUse .getType ();
290+ Document document = bson instanceof BasicDBObject ? new Document (( BasicDBObject ) bson ) : ( Document ) bson ;
291+ TypeInformation <? extends S > typeToRead = typeMapper .readType (document , typeHint );
292+ Class <? extends S > rawType = typeToRead .getType ();
284293
285294 if (conversions .hasCustomReadTarget (bson .getClass (), rawType )) {
286295 return doConvert (bson , rawType );
@@ -303,34 +312,8 @@ private <S extends Object> S doRead(ConversionContext context, TypeInformation<S
303312 return (S ) bson ;
304313 }
305314
306- return context .convert (bson , typeToUse );
307- }
308-
309- /**
310- * Conversion method to materialize an object from a {@link Bson document}. Can be overridden by subclasses.
311- *
312- * @param context must not be {@literal null}
313- * @param bson must not be {@literal null}
314- * @param typeHint the {@link TypeInformation} to be used to unmarshall this {@link Document}.
315- * @return the converted object, will never be {@literal null}.
316- * @since 3.2
317- */
318- @ SuppressWarnings ("unchecked" )
319- protected <S extends Object > S readDocument (ConversionContext context , Bson bson ,
320- TypeInformation <? extends S > typeHint ) {
321-
322- // TODO: Cleanup duplication
323-
324- Document document = bson instanceof BasicDBObject ? new Document ((BasicDBObject ) bson ) : (Document ) bson ;
325- TypeInformation <? extends S > typeToRead = typeMapper .readType (document , typeHint );
326- Class <? extends S > rawType = typeToRead .getType ();
327-
328- if (conversions .hasCustomReadTarget (bson .getClass (), rawType )) {
329- return doConvert (bson , rawType );
330- }
331-
332315 if (typeToRead .isMap ()) {
333- return ( S ) bson ;
316+ return context . convert ( bson , typeToRead ) ;
334317 }
335318
336319 if (BSON .isAssignableFrom (typeHint )) {
@@ -572,9 +555,7 @@ public void write(Object obj, Bson bson) {
572555 Object target = obj instanceof LazyLoadingProxy ? ((LazyLoadingProxy ) obj ).getTarget () : obj ;
573556
574557 writeInternal (target , bson , type );
575- if (MapUtils .asMap (bson ).containsKey ("_id" ) && MapUtils .asMap (bson ).get ("_id" ) == null ) {
576- MapUtils .removeFromMap (bson , "_id" );
577- }
558+ BsonUtils .removeNullId (bson );
578559
579560 if (requiresTypeHint (entityType )) {
580561 typeMapper .writeType (type , bson );
@@ -608,7 +589,7 @@ protected void writeInternal(@Nullable Object obj, Bson bson, @Nullable TypeInfo
608589
609590 if (customTarget .isPresent ()) {
610591 Document result = doConvert (obj , Document .class );
611- MapUtils .addAllToMap (bson , result );
592+ BsonUtils .addAllToMap (bson , result );
612593 return ;
613594 }
614595
@@ -709,12 +690,14 @@ protected void writePropertyInternal(@Nullable Object obj, DocumentAccessor acce
709690 }
710691
711692 if (valueType .isCollectionLike ()) {
712- List <Object > collectionInternal = createCollection (MapUtils .asCollection (obj ), prop );
693+
694+ List <Object > collectionInternal = createCollection (BsonUtils .asCollection (obj ), prop );
713695 accessor .put (prop , collectionInternal );
714696 return ;
715697 }
716698
717699 if (valueType .isMap ()) {
700+
718701 Bson mapDbObj = createMap ((Map <Object , Object >) obj , prop );
719702 accessor .put (prop , mapDbObj );
720703 return ;
@@ -859,7 +842,7 @@ private List<Object> writeCollectionInternal(Collection<?> source, @Nullable Typ
859842 collection .add (getPotentiallyConvertedSimpleWrite (element ,
860843 componentType != null ? componentType .getType () : Object .class ));
861844 } else if (element instanceof Collection || elementType .isArray ()) {
862- collection .add (writeCollectionInternal (MapUtils .asCollection (element ), componentType , new BasicDBList ()));
845+ collection .add (writeCollectionInternal (BsonUtils .asCollection (element ), componentType , new BasicDBList ()));
863846 } else {
864847 Document document = new Document ();
865848 writeInternal (element , document , componentType );
@@ -890,14 +873,14 @@ protected Bson writeMapInternal(Map<Object, Object> obj, Bson bson, TypeInformat
890873 if (val == null || conversions .isSimpleType (val .getClass ())) {
891874 writeSimpleInternal (val , bson , simpleKey );
892875 } else if (val instanceof Collection || val .getClass ().isArray ()) {
893- MapUtils .addToMap (bson , simpleKey ,
894- writeCollectionInternal (MapUtils .asCollection (val ), propertyType .getMapValueType (), new BasicDBList ()));
876+ BsonUtils .addToMap (bson , simpleKey ,
877+ writeCollectionInternal (BsonUtils .asCollection (val ), propertyType .getMapValueType (), new BasicDBList ()));
895878 } else {
896879 Document document = new Document ();
897880 TypeInformation <?> valueTypeInfo = propertyType .isMap () ? propertyType .getMapValueType ()
898881 : ClassTypeInformation .OBJECT ;
899882 writeInternal (val , document , valueTypeInfo );
900- MapUtils .addToMap (bson , simpleKey , document );
883+ BsonUtils .addToMap (bson , simpleKey , document );
901884 }
902885 } else {
903886 throw new MappingException ("Cannot use a complex object as a key value." );
@@ -997,7 +980,7 @@ protected void addCustomTypeKeyIfNecessary(@Nullable TypeInformation<?> type, Ob
997980 * @param key must not be {@literal null}.
998981 */
999982 private void writeSimpleInternal (@ Nullable Object value , Bson bson , String key ) {
1000- MapUtils .addToMap (bson , key , getPotentiallyConvertedSimpleWrite (value , Object .class ));
983+ BsonUtils .addToMap (bson , key , getPotentiallyConvertedSimpleWrite (value , Object .class ));
1001984 }
1002985
1003986 private void writeSimpleInternal (@ Nullable Object value , Bson bson , MongoPersistentProperty property ) {
@@ -1035,7 +1018,7 @@ private Object getPotentiallyConvertedSimpleWrite(@Nullable Object value, @Nulla
10351018 if (value instanceof byte []) {
10361019 return value ;
10371020 }
1038- return MapUtils .asCollection (value );
1021+ return BsonUtils .asCollection (value );
10391022 }
10401023
10411024 return Enum .class .isAssignableFrom (value .getClass ()) ? ((Enum <?>) value ).name () : value ;
@@ -1198,7 +1181,7 @@ protected Map<Object, Object> readMap(ConversionContext context, Bson bson, Type
11981181 Class <?> rawKeyType = keyType != null ? keyType .getType () : Object .class ;
11991182 Class <?> rawValueType = valueType .getType ();
12001183
1201- Map <String , Object > sourceMap = MapUtils .asMap (bson );
1184+ Map <String , Object > sourceMap = BsonUtils .asMap (bson );
12021185 Map <Object , Object > map = CollectionFactory .createMap (mapType , rawKeyType , sourceMap .keySet ().size ());
12031186
12041187 if (!DBRef .class .equals (rawValueType ) && isCollectionOfDbRefWhereBulkFetchIsPossible (sourceMap .values ())) {
@@ -1322,7 +1305,7 @@ public Object convertToMongoType(@Nullable Object obj, MongoPersistentEntity ent
13221305 return newDocument ;
13231306 }
13241307
1325- // TODO: hide
1308+ // TODO: hide in 4.0
13261309 public List <Object > maybeConvertList (Iterable <?> source , @ Nullable TypeInformation <?> typeInformation ) {
13271310
13281311 List <Object > newDbl = new ArrayList <>();
@@ -1462,7 +1445,7 @@ private <T> List<T> bulkReadAndConvertDBRefs(ConversionContext context, List<DBR
14621445
14631446 maybeEmitEvent (
14641447 new AfterLoadEvent <>(document , (Class <T >) type .getType (), collectionName ));
1465- target = (T ) doRead (context , type , document );
1448+ target = (T ) readDocument (context , document , type );
14661449 }
14671450
14681451 if (target != null ) {
0 commit comments