/** Sets the fetch plan to use. */
 public OQuery<T> setFetchPlan(final String fetchPlan) {
   OFetchHelper.checkFetchPlanValid(fetchPlan);
   if (fetchPlan != null && fetchPlan.length() == 0) this.fetchPlan = null;
   else this.fetchPlan = fetchPlan;
   return this;
 }
  public <RET extends ORecordInternal<?>> RET executeReadRecord(
      final ORecordId iRid,
      ORecordInternal<?> iRecord,
      final String iFetchPlan,
      final boolean iIgnoreCache) {
    checkOpeness();

    // setCurrentDatabaseinThreadLocal();

    try {
      checkSecurity(
          ODatabaseSecurityResources.CLUSTER,
          ORole.PERMISSION_READ,
          getClusterNameById(iRid.getClusterId()));

      // SEARCH IN LOCAL TX
      ORecordInternal<?> record = getTransaction().getRecord(iRid);
      if (record == null && !iIgnoreCache)
        // SEARCH INTO THE CACHE
        record = getLevel1Cache().findRecord(iRid);

      if (record != null) {
        OFetchHelper.checkFetchPlanValid(iFetchPlan);
        callbackHooks(TYPE.BEFORE_READ, record);

        if (record.getInternalStatus() == ORecordElement.STATUS.NOT_LOADED) record.reload();

        callbackHooks(TYPE.AFTER_READ, record);
        return (RET) record;
      }

      final ORawBuffer recordBuffer = underlying.read(iRid, iFetchPlan);
      if (recordBuffer == null) return null;

      if (iRecord == null || iRecord.getRecordType() != recordBuffer.recordType)
        // NO SAME RECORD TYPE: CAN'T REUSE OLD ONE BUT CREATE A NEW ONE FOR IT
        iRecord = Orient.instance().getRecordFactoryManager().newInstance(recordBuffer.recordType);

      iRecord.fill(iRid, recordBuffer.version, recordBuffer.buffer, false);

      callbackHooks(TYPE.BEFORE_READ, iRecord);

      iRecord.fromStream(recordBuffer.buffer);
      iRecord.setInternalStatus(ORecordElement.STATUS.LOADED);

      callbackHooks(TYPE.AFTER_READ, iRecord);

      if (!iIgnoreCache) getLevel1Cache().updateRecord(iRecord);

      return (RET) iRecord;
    } catch (OException e) {
      // RE-THROW THE EXCEPTION
      throw e;

    } catch (Exception e) {
      // WRAP IT AS ODATABASE EXCEPTION
      OLogManager.instance()
          .exception("Error on retrieving record " + iRid, e, ODatabaseException.class);
    }
    return null;
  }