core/src/main/java/com/orientechnologies/orient/core/db/document/ODatabaseDocumentAbstract.java
@Override
  public <RET extends ORecord> RET save(ORecord iRecord, String iClusterName, final OPERATION_MODE iMode, boolean iForceCreate,
      final ORecordCallback<? extends Number> iRecordCreatedCallback, ORecordCallback<Integer> iRecordUpdatedCallback) {
    checkOpenness();

    if (iRecord instanceof OVertex) {
      iRecord = iRecord.getRecord();
    }
    if (iRecord instanceof OEdge) {
      if (((OEdge) iRecord).isLightweight()) {
        iRecord = ((OEdge) iRecord).getFrom();
      } else {
        iRecord = iRecord.getRecord();
      }
    }

    ODirtyManager dirtyManager = ORecordInternal.getDirtyManager(iRecord);
    if (iRecord instanceof OElement && dirtyManager != null && dirtyManager.getReferences() != null && !dirtyManager.getReferences()
        .isEmpty()) {
      if ((((OElement) iRecord).isVertex() || ((OElement) iRecord).isEdge()) && !getTransaction().isActive() && inHook.isEmpty()) {
        return saveGraph(iRecord, iClusterName, iMode, iForceCreate, iRecordCreatedCallback, iRecordUpdatedCallback);
      }
    }
    return saveInternal(iRecord, iClusterName, iMode, iForceCreate, iRecordCreatedCallback, iRecordUpdatedCallback);
  }
@Override
  public <RET extends ORecord> RET save(ORecord iRecord, String iClusterName, final OPERATION_MODE iMode, boolean iForceCreate,
      final ORecordCallback<? extends Number> iRecordCreatedCallback, ORecordCallback<Integer> iRecordUpdatedCallback) {
    checkOpenness();

    if (iRecord instanceof OVertex) {
      iRecord = iRecord.getRecord();
    }
    if (iRecord instanceof OEdge) {
      if (((OEdge) iRecord).isLightweight()) {
        iRecord = ((OEdge) iRecord).getFrom();
      } else {
        iRecord = iRecord.getRecord();
      }
    }

    ODirtyManager dirtyManager = ORecordInternal.getDirtyManager(iRecord);
    if (iRecord instanceof OElement && dirtyManager != null && dirtyManager.getReferences() != null && !dirtyManager.getReferences()
        .isEmpty()) {
      if ((((OElement) iRecord).isVertex() || ((OElement) iRecord).isEdge()) && !getTransaction().isActive() && inHook.isEmpty()) {
        return saveGraph(iRecord, iClusterName, iMode, iForceCreate, iRecordCreatedCallback, iRecordUpdatedCallback);
      }
    }
    return saveInternal(iRecord, iClusterName, iMode, iForceCreate, iRecordCreatedCallback, iRecordUpdatedCallback);
  }
Saves a document specifying a cluster where to store the record. Behavior depends by the current running transaction if any. If
no transaction is running then changes apply immediately. If an Optimistic transaction is running then the record will be
changed at commit time. The current transaction will continue to see the record as modified, while others not. If a Pessimistic
transaction is running, then an exclusive lock is acquired against the record. Current transaction will continue to see the
record as modified, while others cannot access to it since it's locked.
<p>
If MVCC is enabled and the version of the document is different by the version stored in the database, then a {@link
OConcurrentModificationException} exception is thrown. Before to save the document it must be valid following the constraints
declared in the schema if any (can work also in schema-less mode). To validate the document the {@link ODocument#validate()} is
called.

@param iRecord                Record to save
@param iClusterName           Cluster name where to save the record
@param iMode                  Mode of save: synchronous (default) or asynchronous
@param iForceCreate           Flag that indicates that record should be created. If record with current rid already exists,
exception is thrown
@param iRecordCreatedCallback callback that is called after creation of new record
@param iRecordUpdatedCallback callback that is called after record update

@return The Database instance itself giving a "fluent interface". Useful to call multiple methods in chain.

@throws OConcurrentModificationException if the version of the document is different by the version contained in the database.
@throws OValidationException             if the document breaks some validation constraints defined in the schema
@see #setMVCC(boolean), {@link #isMVCC()}, ODocument#validate()