object/src/main/java/com/orientechnologies/orient/object/enhancement/OObjectProxyMethodHandler.java
public void detachAll(final Object self, final boolean nonProxiedInstance, final Map<Object, Object> alreadyDetached,
      final Map<Object, Object> lazyObjects) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final Class<?> selfClass = self.getClass();

    for (String fieldName : doc.fieldNames()) {
      final Field field = OObjectEntitySerializer.getField(fieldName, selfClass);
      if (field != null) {
        Object value = getValue(self, fieldName, false, null, true);
        if (value instanceof OObjectLazyMultivalueElement) {
          ((OObjectLazyMultivalueElement<?>) value).detachAll(nonProxiedInstance, alreadyDetached, lazyObjects);
          if (nonProxiedInstance)
            value = ((OObjectLazyMultivalueElement<?>) value).getNonOrientInstance();
        } else if (value instanceof Proxy) {
          OObjectProxyMethodHandler handler = (OObjectProxyMethodHandler) ((ProxyObject) value).getHandler();
          if (nonProxiedInstance) {
            value = OObjectEntitySerializer.getNonProxiedInstance(value);
          }

          if (OObjectEntitySerializer.isFetchLazyField(self.getClass(), fieldName)) {
            // just make a placeholder with only the id, so it can be fetched later (but not by orient
            // internally)
            // do not use the already detached map for this, that might mix up lazy and non-lazy objects
            Object lazyValue = lazyObjects.get(handler.doc.getIdentity());
            if (lazyValue != null) {
              value = lazyValue;
            } else {
              OObjectEntitySerializer.setIdField(field.getType(), value, handler.doc.getIdentity());
              lazyObjects.put(handler.doc.getIdentity(), value);
            }
          } else {
            Object detachedValue = alreadyDetached.get(handler.doc.getIdentity());
            if (detachedValue != null) {
              value = detachedValue;
            } else {
              ORID identity = handler.doc.getIdentity();
              if (identity.isValid())
                alreadyDetached.put(identity, value);
              handler.detachAll(value, nonProxiedInstance, alreadyDetached, lazyObjects);
            }
          }
        } else if (value instanceof OTrackedMap && nonProxiedInstance) {
          Map newValue = new LinkedHashMap<>();
          newValue.putAll((Map) value);
          value = newValue;
        } else if (value instanceof OTrackedList && nonProxiedInstance) {
          List newValue = new ArrayList();
          newValue.addAll((Collection) value);
          value = newValue;
        } else if (value instanceof OTrackedSet && nonProxiedInstance) {
          Set newValue = new LinkedHashSet();
          newValue.addAll((Collection) value);
          value = newValue;
        }
        OObjectEntitySerializer.setFieldValue(field, self, value);
      }
    }
    OObjectEntitySerializer.setIdField(selfClass, self, doc.getIdentity());
    OObjectEntitySerializer.setVersionField(selfClass, self, doc.getVersion());
  }
public void detachAll(final Object self, final boolean nonProxiedInstance, final Map<Object, Object> alreadyDetached,
      final Map<Object, Object> lazyObjects) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final Class<?> selfClass = self.getClass();

    for (String fieldName : doc.fieldNames()) {
      final Field field = OObjectEntitySerializer.getField(fieldName, selfClass);
      if (field != null) {
        Object value = getValue(self, fieldName, false, null, true);
        if (value instanceof OObjectLazyMultivalueElement) {
          ((OObjectLazyMultivalueElement<?>) value).detachAll(nonProxiedInstance, alreadyDetached, lazyObjects);
          if (nonProxiedInstance)
            value = ((OObjectLazyMultivalueElement<?>) value).getNonOrientInstance();
        } else if (value instanceof Proxy) {
          OObjectProxyMethodHandler handler = (OObjectProxyMethodHandler) ((ProxyObject) value).getHandler();
          if (nonProxiedInstance) {
            value = OObjectEntitySerializer.getNonProxiedInstance(value);
          }

          if (OObjectEntitySerializer.isFetchLazyField(self.getClass(), fieldName)) {
            // just make a placeholder with only the id, so it can be fetched later (but not by orient
            // internally)
            // do not use the already detached map for this, that might mix up lazy and non-lazy objects
            Object lazyValue = lazyObjects.get(handler.doc.getIdentity());
            if (lazyValue != null) {
              value = lazyValue;
            } else {
              OObjectEntitySerializer.setIdField(field.getType(), value, handler.doc.getIdentity());
              lazyObjects.put(handler.doc.getIdentity(), value);
            }
          } else {
            Object detachedValue = alreadyDetached.get(handler.doc.getIdentity());
            if (detachedValue != null) {
              value = detachedValue;
            } else {
              ORID identity = handler.doc.getIdentity();
              if (identity.isValid())
                alreadyDetached.put(identity, value);
              handler.detachAll(value, nonProxiedInstance, alreadyDetached, lazyObjects);
            }
          }
        } else if (value instanceof OTrackedMap && nonProxiedInstance) {
          Map newValue = new LinkedHashMap<>();
          newValue.putAll((Map) value);
          value = newValue;
        } else if (value instanceof OTrackedList && nonProxiedInstance) {
          List newValue = new ArrayList();
          newValue.addAll((Collection) value);
          value = newValue;
        } else if (value instanceof OTrackedSet && nonProxiedInstance) {
          Set newValue = new LinkedHashSet();
          newValue.addAll((Collection) value);
          value = newValue;
        }
        OObjectEntitySerializer.setFieldValue(field, self, value);
      }
    }
    OObjectEntitySerializer.setIdField(selfClass, self, doc.getIdentity());
    OObjectEntitySerializer.setVersionField(selfClass, self, doc.getVersion());
  }
Method that detaches all fields contained in the document to the given object

@param self :- The object containing this handler instance

@throws InvocationTargetException
@throws IllegalAccessException
@throws NoSuchMethodException