/** * Writes the given {@link Map} using the given {@link MongoPersistentProperty} information. * * @param map must not {@literal null}. * @param property must not be {@literal null}. * @return */ protected DBObject createMap(Map<Object, Object> map, MongoPersistentProperty property) { Assert.notNull(map, "Given map must not be null!"); Assert.notNull(property, "PersistentProperty must not be null!"); if (!property.isDbReference()) { return writeMapInternal(map, new BasicDBObject(), property.getTypeInformation()); } BasicDBObject dbObject = new BasicDBObject(); for (Map.Entry<Object, Object> entry : map.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); if (conversions.isSimpleType(key.getClass())) { String simpleKey = prepareMapKey(key.toString()); dbObject.put(simpleKey, value != null ? createDBRef(value, property) : null); } else { throw new MappingException("Cannot use a complex object as a key value."); } } return dbObject; }
/** * Writes the given {@link Collection} using the given {@link MongoPersistentProperty} * information. * * @param collection must not be {@literal null}. * @param property must not be {@literal null}. * @return */ protected DBObject createCollection(Collection<?> collection, MongoPersistentProperty property) { if (!property.isDbReference()) { return writeCollectionInternal(collection, property.getTypeInformation(), new BasicDBList()); } BasicDBList dbList = new BasicDBList(); for (Object element : collection) { if (element == null) { continue; } DBRef dbRef = createDBRef(element, property); dbList.add(dbRef); } return dbList; }
@SuppressWarnings({"unchecked"}) protected void writePropertyInternal(Object obj, DBObject dbo, MongoPersistentProperty prop) { if (obj == null) { return; } DBObjectAccessor accessor = new DBObjectAccessor(dbo); TypeInformation<?> valueType = ClassTypeInformation.from(obj.getClass()); TypeInformation<?> type = prop.getTypeInformation(); if (valueType.isCollectionLike()) { DBObject collectionInternal = createCollection(asCollection(obj), prop); accessor.put(prop, collectionInternal); return; } if (valueType.isMap()) { DBObject mapDbObj = createMap((Map<Object, Object>) obj, prop); accessor.put(prop, mapDbObj); return; } if (prop.isDbReference()) { DBRef dbRefObj = null; /* * If we already have a LazyLoadingProxy, we use it's cached DBRef value instead of * unnecessarily initializing it only to convert it to a DBRef a few instructions later. */ if (obj instanceof LazyLoadingProxy) { dbRefObj = ((LazyLoadingProxy) obj).toDBRef(); } dbRefObj = dbRefObj != null ? dbRefObj : createDBRef(obj, prop); if (null != dbRefObj) { accessor.put(prop, dbRefObj); return; } } /* * If we have a LazyLoadingProxy we make sure it is initialized first. */ if (obj instanceof LazyLoadingProxy) { obj = ((LazyLoadingProxy) obj).getTarget(); } // Lookup potential custom target type Class<?> basicTargetType = conversions.getCustomWriteTarget(obj.getClass(), null); if (basicTargetType != null) { accessor.put(prop, conversionService.convert(obj, basicTargetType)); return; } Object existingValue = accessor.get(prop); BasicDBObject propDbObj = existingValue instanceof BasicDBObject ? (BasicDBObject) existingValue : new BasicDBObject(); addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, propDbObj); MongoPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass()) ? mappingContext.getPersistentEntity(obj.getClass()) : mappingContext.getPersistentEntity(type); writeInternal(obj, propDbObj, entity); accessor.put(prop, propDbObj); }