object/src/main/java/com/orientechnologies/orient/object/serialization/OObjectSerializerHelper.java
public static ODocument toStream(final Object iPojo, final ODocument iRecord, final OEntityManager iEntityManager,
      final OClass schemaClass, final OUserObject2RecordHandler iObj2RecHandler, final ODatabaseObject db,
      final boolean iSaveOnlyDirty) {
    if (iSaveOnlyDirty && !iRecord.isDirty())
      return iRecord;

    final long timer = Orient.instance().getProfiler().startChrono();

    final Integer identityRecord = System.identityHashCode(iRecord);

    if (OSerializationThreadLocal.INSTANCE.get().contains(identityRecord))
      return iRecord;

    OSerializationThreadLocal.INSTANCE.get().add(identityRecord);

    OProperty schemaProperty;

    final Class<?> pojoClass = iPojo.getClass();

    final List<Field> properties = getClassFields(pojoClass);

    // CHECK FOR ID BINDING
    final Field idField = fieldIds.get(pojoClass);
    if (idField != null) {
      Object id = getFieldValue(iPojo, idField.getName());
      if (id != null) {
        // FOUND
        if (id instanceof ORecordId) {
          ORecordInternal.setIdentity(iRecord, (ORecordId) id);
        } else if (id instanceof Number) {
          // TREATS AS CLUSTER POSITION
          ((ORecordId) iRecord.getIdentity()).setClusterId(schemaClass.getDefaultClusterId());
          ((ORecordId) iRecord.getIdentity()).setClusterPosition(((Number) id).longValue());
        } else if (id instanceof String)
          ((ORecordId) iRecord.getIdentity()).fromString((String) id);
        else if (id.getClass().equals(Object.class))
          ORecordInternal.setIdentity(iRecord, (ORecordId) id);
        else
          OLogManager.instance().warn(OObjectSerializerHelper.class,
              "@Id field has been declared as %s while the supported are: ORID, Number, String, Object", id.getClass());
      }
    }

    // CHECK FOR VERSION BINDING
    final Field vField = fieldVersions.get(pojoClass);
    boolean versionConfigured = false;
    if (vField != null) {
      versionConfigured = true;
      Object ver = getFieldValue(iPojo, vField.getName());

      final int version = convertVersion(ver);
      ORecordInternal.setVersion(iRecord, version);
    }

    if (db.isMVCC() && !versionConfigured && db.getTransaction() instanceof OTransactionOptimistic)
      throw new OTransactionException("Cannot involve an object of class '" + pojoClass
          + "' in an Optimistic Transaction commit because it does not define @Version or @OVersion and therefore cannot handle MVCC");

    // SET OBJECT CLASS
    iRecord.setClassName(schemaClass != null ? schemaClass.getName() : null);

    String fieldName;
    Object fieldValue;

    // CALL BEFORE MARSHALLING
    invokeCallback(iPojo, iRecord, OBeforeSerialization.class);

    for (Field p : properties) {
      fieldName = p.getName();

      if (idField != null && fieldName.equals(idField.getName()))
        continue;

      if (vField != null && fieldName.equals(vField.getName()))
        continue;

      fieldValue = serializeFieldValue(getFieldType(iPojo, fieldName), getFieldValue(iPojo, fieldName));

      schemaProperty = schemaClass != null ? schemaClass.getProperty(fieldName) : null;

      if (fieldValue != null) {
        if (isEmbeddedObject(iPojo.getClass(), fieldValue.getClass(), fieldName, iEntityManager)) {
          // AUTO CREATE SCHEMA PROPERTY
          if (schemaClass == null) {
            db.getMetadata().getSchema().createClass(iPojo.getClass());
            iRecord.setClassNameIfExists(iPojo.getClass().getSimpleName());
          }

          if (schemaProperty == null) {
            OType t = OType.getTypeByClass(fieldValue.getClass());
            if (t == null)
              t = OType.EMBEDDED;
            schemaProperty = iRecord.getSchemaClass().createProperty(fieldName, t);
          }
        }
      }

      fieldValue = typeToStream(fieldValue, schemaProperty != null ? schemaProperty.getType() : null, iEntityManager,
          iObj2RecHandler, db, iRecord, iSaveOnlyDirty);

      iRecord.field(fieldName, fieldValue);
    }

    iObj2RecHandler.registerUserObject(iPojo, iRecord);

    // CALL AFTER MARSHALLING
    invokeCallback(iPojo, iRecord, OAfterSerialization.class);

    OSerializationThreadLocal.INSTANCE.get().remove(identityRecord);

    Orient.instance().getProfiler().stopChrono("Object.toStream", "Serialize object to stream", timer);

    return iRecord;
  }
public static ODocument toStream(final Object iPojo, final ODocument iRecord, final OEntityManager iEntityManager,
      final OClass schemaClass, final OUserObject2RecordHandler iObj2RecHandler, final ODatabaseObject db,
      final boolean iSaveOnlyDirty) {
    if (iSaveOnlyDirty && !iRecord.isDirty())
      return iRecord;

    final long timer = Orient.instance().getProfiler().startChrono();

    final Integer identityRecord = System.identityHashCode(iRecord);

    if (OSerializationThreadLocal.INSTANCE.get().contains(identityRecord))
      return iRecord;

    OSerializationThreadLocal.INSTANCE.get().add(identityRecord);

    OProperty schemaProperty;

    final Class<?> pojoClass = iPojo.getClass();

    final List<Field> properties = getClassFields(pojoClass);

    // CHECK FOR ID BINDING
    final Field idField = fieldIds.get(pojoClass);
    if (idField != null) {
      Object id = getFieldValue(iPojo, idField.getName());
      if (id != null) {
        // FOUND
        if (id instanceof ORecordId) {
          ORecordInternal.setIdentity(iRecord, (ORecordId) id);
        } else if (id instanceof Number) {
          // TREATS AS CLUSTER POSITION
          ((ORecordId) iRecord.getIdentity()).setClusterId(schemaClass.getDefaultClusterId());
          ((ORecordId) iRecord.getIdentity()).setClusterPosition(((Number) id).longValue());
        } else if (id instanceof String)
          ((ORecordId) iRecord.getIdentity()).fromString((String) id);
        else if (id.getClass().equals(Object.class))
          ORecordInternal.setIdentity(iRecord, (ORecordId) id);
        else
          OLogManager.instance().warn(OObjectSerializerHelper.class,
              "@Id field has been declared as %s while the supported are: ORID, Number, String, Object", id.getClass());
      }
    }

    // CHECK FOR VERSION BINDING
    final Field vField = fieldVersions.get(pojoClass);
    boolean versionConfigured = false;
    if (vField != null) {
      versionConfigured = true;
      Object ver = getFieldValue(iPojo, vField.getName());

      final int version = convertVersion(ver);
      ORecordInternal.setVersion(iRecord, version);
    }

    if (db.isMVCC() && !versionConfigured && db.getTransaction() instanceof OTransactionOptimistic)
      throw new OTransactionException("Cannot involve an object of class '" + pojoClass
          + "' in an Optimistic Transaction commit because it does not define @Version or @OVersion and therefore cannot handle MVCC");

    // SET OBJECT CLASS
    iRecord.setClassName(schemaClass != null ? schemaClass.getName() : null);

    String fieldName;
    Object fieldValue;

    // CALL BEFORE MARSHALLING
    invokeCallback(iPojo, iRecord, OBeforeSerialization.class);

    for (Field p : properties) {
      fieldName = p.getName();

      if (idField != null && fieldName.equals(idField.getName()))
        continue;

      if (vField != null && fieldName.equals(vField.getName()))
        continue;

      fieldValue = serializeFieldValue(getFieldType(iPojo, fieldName), getFieldValue(iPojo, fieldName));

      schemaProperty = schemaClass != null ? schemaClass.getProperty(fieldName) : null;

      if (fieldValue != null) {
        if (isEmbeddedObject(iPojo.getClass(), fieldValue.getClass(), fieldName, iEntityManager)) {
          // AUTO CREATE SCHEMA PROPERTY
          if (schemaClass == null) {
            db.getMetadata().getSchema().createClass(iPojo.getClass());
            iRecord.setClassNameIfExists(iPojo.getClass().getSimpleName());
          }

          if (schemaProperty == null) {
            OType t = OType.getTypeByClass(fieldValue.getClass());
            if (t == null)
              t = OType.EMBEDDED;
            schemaProperty = iRecord.getSchemaClass().createProperty(fieldName, t);
          }
        }
      }

      fieldValue = typeToStream(fieldValue, schemaProperty != null ? schemaProperty.getType() : null, iEntityManager,
          iObj2RecHandler, db, iRecord, iSaveOnlyDirty);

      iRecord.field(fieldName, fieldValue);
    }

    iObj2RecHandler.registerUserObject(iPojo, iRecord);

    // CALL AFTER MARSHALLING
    invokeCallback(iPojo, iRecord, OAfterSerialization.class);

    OSerializationThreadLocal.INSTANCE.get().remove(identityRecord);

    Orient.instance().getProfiler().stopChrono("Object.toStream", "Serialize object to stream", timer);

    return iRecord;
  }
Serialize the user POJO to a ORecordDocument instance.

@param iPojo
User pojo to serialize
@param iRecord
Record where to update
@param iObj2RecHandler