Source:
private Object readCollectionOrArray(TypeInformation<?> targetType, List sourceValue, ObjectPath path) { Assert.notNull(targetType, "Target type must not be null!"); Assert.notNull(path, "Object path must not be null!"); Class<?> collectionType = targetType.getType(); TypeInformation<?> componentType = targetType.getComponentType().orElse(ClassTypeInformation.OBJECT); Class<?> rawComponentType = componentType.getType(); collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>() : CollectionFactory.createCollection(collectionType, rawComponentType, sourceValue.size()); if (sourceValue.isEmpty()) { return getPotentiallyConvertedSimpleRead(items, collectionType); } if (!DBRef.class.equals(rawComponentType) && isCollectionOfDbRefWhereBulkFetchIsPossible(sourceValue)) { List<Object> objects = bulkReadAndConvertDBRefs((List<DBRef>) sourceValue, componentType, path, rawComponentType); return getPotentiallyConvertedSimpleRead(objects, targetType.getType()); } for (Object dbObjItem : sourceValue) { if (dbObjItem instanceof DBRef) { items.add(DBRef.class.equals(rawComponentType) ? dbObjItem : readAndConvertDBRef((DBRef) dbObjItem, componentType, path, rawComponentType)); } else if (dbObjItem instanceof Document) { items.add(read(componentType, (Document) dbObjItem, path)); } else if (dbObjItem instanceof BasicDBObject) { items.add(read(componentType, (BasicDBObject) dbObjItem, path)); } else { if (dbObjItem instanceof Collection) { if (!rawComponentType.isArray() && !ClassUtils.isAssignable(Iterable.class, rawComponentType)) { throw new MappingException( String.format(INCOMPATIBLE_TYPES, dbObjItem, dbObjItem.getClass(), rawComponentType, path)); } } if (dbObjItem instanceof List) { items.add(readCollectionOrArray(ClassTypeInformation.OBJECT, (List) dbObjItem, path)); } else { items.add(getPotentiallyConvertedSimpleRead(dbObjItem, rawComponentType)); } } } return getPotentiallyConvertedSimpleRead(items, targetType.getType()); }

Target:
private Object readCollectionOrArray(TypeInformation<?> targetType, List sourceValue, ObjectPath path) { Assert.notNull(targetType, "Target type must not be null!"); Assert.notNull(path, "Object path must not be null!"); Class<?> collectionType = targetType.getType(); TypeInformation<?> componentType = targetType.getComponentType().orElse(ClassTypeInformation.OBJECT); Class<?> rawComponentType = componentType.getType(); collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection<Object> items = targetType.getType().isArray() ? new ArrayList<>(sourceValue.size()) : CollectionFactory.createCollection(collectionType, rawComponentType, sourceValue.size()); if (sourceValue.isEmpty()) { return getPotentiallyConvertedSimpleRead(items, collectionType); } if (!DBRef.class.equals(rawComponentType) && isCollectionOfDbRefWhereBulkFetchIsPossible(sourceValue)) { List<Object> objects = bulkReadAndConvertDBRefs((List<DBRef>) sourceValue, componentType, path, rawComponentType); return getPotentiallyConvertedSimpleRead(objects, targetType.getType()); } for (Object dbObjItem : sourceValue) { if (dbObjItem instanceof DBRef) { items.add(DBRef.class.equals(rawComponentType) ? dbObjItem : readAndConvertDBRef((DBRef) dbObjItem, componentType, path, rawComponentType)); } else if (dbObjItem instanceof Document) { items.add(read(componentType, (Document) dbObjItem, path)); } else if (dbObjItem instanceof BasicDBObject) { items.add(read(componentType, (BasicDBObject) dbObjItem, path)); } else { if (dbObjItem instanceof Collection) { if (!rawComponentType.isArray() && !ClassUtils.isAssignable(Iterable.class, rawComponentType)) { throw new MappingException( String.format(INCOMPATIBLE_TYPES, dbObjItem, dbObjItem.getClass(), rawComponentType, path)); } } if (dbObjItem instanceof List) { items.add(readCollectionOrArray(ClassTypeInformation.OBJECT, (List) dbObjItem, path)); } else { items.add(getPotentiallyConvertedSimpleRead(dbObjItem, rawComponentType)); } } } return getPotentiallyConvertedSimpleRead(items, targetType.getType()); }