private <S extends Object> S read( final MongoPersistentEntity<S> entity, final DBObject dbo, final ObjectPath path) { final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(dbo, spELContext); ParameterValueProvider<MongoPersistentProperty> provider = getParameterProvider(entity, dbo, evaluator, path); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); S instance = instantiator.createInstance(entity, provider); final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance), conversionService); final MongoPersistentProperty idProperty = entity.getIdProperty(); final S result = instance; // make sure id property is set before all other properties Object idValue = null; if (idProperty != null) { idValue = getValueInternal(idProperty, dbo, evaluator, path); accessor.setProperty(idProperty, idValue); } final ObjectPath currentPath = path.push(result, entity, idValue != null ? dbo.get(idProperty.getFieldName()) : null); // Set properties not already set in the constructor entity.doWithProperties( new PropertyHandler<MongoPersistentProperty>() { public void doWithPersistentProperty(MongoPersistentProperty prop) { // we skip the id property since it was already set if (idProperty != null && idProperty.equals(prop)) { return; } if (!dbo.containsField(prop.getFieldName()) || entity.isConstructorArgument(prop)) { return; } accessor.setProperty(prop, getValueInternal(prop, dbo, evaluator, currentPath)); } }); // Handle associations entity.doWithAssociations( new AssociationHandler<MongoPersistentProperty>() { public void doWithAssociation(Association<MongoPersistentProperty> association) { final MongoPersistentProperty property = association.getInverse(); Object value = dbo.get(property.getFieldName()); if (value == null || entity.isConstructorArgument(property)) { return; } DBRef dbref = value instanceof DBRef ? (DBRef) value : null; DbRefProxyHandler handler = new DefaultDbRefProxyHandler( spELContext, mappingContext, MappingMongoConverter.this); DbRefResolverCallback callback = new DefaultDbRefResolverCallback( dbo, currentPath, evaluator, MappingMongoConverter.this); accessor.setProperty( property, dbRefResolver.resolveDbRef(property, dbref, callback, handler)); } }); return result; }