public Object getObject(ExecutionContext ec, ResultSet resultSet, int[] exprIndex) {
    if (exprIndex == null) {
      return null;
    }

    Object datastoreValue = getDatastoreMapping(0).getObject(resultSet, exprIndex[0]);
    if (datastoreValue == null) {
      return null;
    }

    if (datastoreValue instanceof String) {
      TypeConverter conv =
          ec.getNucleusContext()
              .getTypeManager()
              .getTypeConverterForType(LocalTime.class, String.class);
      if (conv != null) {
        return conv.toMemberType(datastoreValue);
      } else {
        throw new NucleusUserException("This type doesn't support persistence as a String");
      }
    } else if (datastoreValue instanceof Time) {
      Time time = (Time) datastoreValue;
      Calendar cal = Calendar.getInstance();
      cal.setTime(time);
      LocalTime localTime =
          LocalTime.of(
              cal.get(Calendar.HOUR_OF_DAY),
              cal.get(Calendar.MINUTE),
              cal.get(Calendar.SECOND),
              cal.get(Calendar.MILLISECOND) * 1000000);
      return localTime;
    } else {
      return null;
    }
  }
  /** Method to delete the object from the datastore. */
  protected void internalDeletePersistent() {
    if (isDeleting()) {
      throw new NucleusUserException(Localiser.msg("026008"));
    }

    activity = ActivityState.DELETING;
    try {
      if (dirty) {
        clearDirtyFlags();

        // Clear the PM's knowledge of our being dirty. This calls flush() which does nothing
        myEC.flushInternal(false);
      }

      myEC.getNucleusContext();
      if (!isEmbedded()) {
        // Nothing to delete if embedded
        getStoreManager().getPersistenceHandler().deleteObject(this);
      }

      preDeleteLoadedFields = null;
    } finally {
      activity = ActivityState.NONE;
    }
  }
  /**
   * Method to find an object value generator based on its name. Caches the generators once
   * generated.
   *
   * @param ec ExecutionContext
   * @param genName The generator name
   * @return The value generator (if any)
   * @throws NucleusException if no generator of that name is found
   */
  protected static ObjectValueGenerator getObjectValueGenerator(
      ExecutionContext ec, String genName) {
    if (!objectValGenerators.isEmpty()) {
      ObjectValueGenerator valGen = objectValGenerators.get(genName);
      if (valGen != null) {
        return valGen;
      }
    }

    try {
      ObjectValueGenerator valGen =
          (ObjectValueGenerator)
              ec.getNucleusContext()
                  .getPluginManager()
                  .createExecutableExtension(
                      "org.datanucleus.store_objectvaluegenerator",
                      new String[] {"name"},
                      new String[] {genName},
                      "class-name",
                      null,
                      null);
      objectValGenerators.put(genName, valGen);
      return valGen;
    } catch (Exception e) {
      NucleusLogger.VALUEGENERATION.info(
          "Exception thrown generating value using objectvaluegenerator " + genName, e);
      throw new NucleusException("Exception thrown generating value for object", e);
    }
  }
  /**
   * Convenience method to retrieve field values from an L2 cached object if they are loaded in that
   * object. If the object is not in the L2 cache then just returns, and similarly if the required
   * fields aren't available.
   *
   * @param fieldNumbers Numbers of fields to load from the L2 cache
   * @return The fields that couldn't be loaded
   */
  protected int[] loadFieldsFromLevel2Cache(int[] fieldNumbers) {
    // Only continue if there are fields, and not being deleted/flushed etc
    if (fieldNumbers == null
        || fieldNumbers.length == 0
        || myEC.isFlushing()
        || myLC.isDeleted()
        || isDeleting()
        || getExecutionContext().getTransaction().isCommitting()) {
      return fieldNumbers;
    }
    // TODO Drop this check when we're confident that this doesn't affect some use-cases
    if (!myEC.getNucleusContext()
        .getConfiguration()
        .getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_LOADFIELDS, true)) {
      return fieldNumbers;
    }

    Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
    if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd)) {
      CachedPC<T> cachedPC = l2cache.get(myID);
      if (cachedPC != null) {
        int[] cacheFieldsToLoad =
            ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, true);
        if (cacheFieldsToLoad != null && cacheFieldsToLoad.length > 0) {
          if (NucleusLogger.CACHE.isDebugEnabled()) {
            NucleusLogger.CACHE.debug(
                Localiser.msg(
                    "026034",
                    StringUtils.toJVMIDString(getObject()),
                    myID,
                    StringUtils.intArrayToString(cacheFieldsToLoad)));
          }

          L2CacheRetrieveFieldManager l2RetFM = new L2CacheRetrieveFieldManager(this, cachedPC);
          this.replaceFields(cacheFieldsToLoad, l2RetFM);
          int[] fieldsNotLoaded = l2RetFM.getFieldsNotLoaded();
          if (fieldsNotLoaded != null) {
            for (int i = 0; i < fieldsNotLoaded.length; i++) {
              loadedFields[fieldsNotLoaded[i]] = false;
            }
          }
        }
      }
    }

    return ClassUtils.getFlagsSetTo(loadedFields, fieldNumbers, false);
  }
  /**
   * Convenience method to update a Level2 cached version of this object if cacheable and has not
   * been modified during this transaction.
   *
   * @param fieldNumbers Numbers of fields to update in L2 cached object
   */
  protected void updateLevel2CacheForFields(int[] fieldNumbers) {
    String updateMode = (String) myEC.getProperty(PropertyNames.PROPERTY_CACHE_L2_UPDATE_MODE);
    if (updateMode != null && updateMode.equalsIgnoreCase("commit-only")) {
      return;
    }
    if (fieldNumbers == null || fieldNumbers.length == 0) {
      return;
    }

    Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
    if (l2cache != null
        && myEC.getNucleusContext().isClassCacheable(cmd)
        && !myEC.isObjectModifiedInTransaction(myID)) {
      CachedPC<T> cachedPC = l2cache.get(myID);
      if (cachedPC != null) {
        // This originally just updated the L2 cache for fields where the L2 cache didn't have a
        // value for that field, like this
        /*
        int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, false);
        if (cacheFieldsToLoad == null || cacheFieldsToLoad.length == 0)
        {
            return;
        }
        */
        int[] cacheFieldsToLoad = fieldNumbers;
        CachedPC copyCachedPC = cachedPC.getCopy();
        if (NucleusLogger.CACHE.isDebugEnabled()) {
          NucleusLogger.CACHE.debug(
              Localiser.msg(
                  "026033",
                  StringUtils.toJVMIDString(getObject()),
                  myID,
                  StringUtils.intArrayToString(cacheFieldsToLoad)));
        }

        provideFields(cacheFieldsToLoad, new L2CachePopulateFieldManager(this, copyCachedPC));

        // Replace the current L2 cached object with this one
        myEC.getNucleusContext().getLevel2Cache().put(getInternalObjectId(), copyCachedPC);
      }
    }
  }
  /** Method to change the object state to evicted. */
  public void evict() {
    if (myLC != myEC.getNucleusContext().getApiAdapter().getLifeCycleState(LifeCycleState.P_CLEAN)
        && myLC
            != myEC.getNucleusContext()
                .getApiAdapter()
                .getLifeCycleState(LifeCycleState.P_NONTRANS)) {
      return;
    }

    preStateChange();
    try {
      try {
        getCallbackHandler().preClear(getObject());

        getCallbackHandler().postClear(getObject());
      } finally {
        myLC = myLC.transitionEvict(this);
      }
    } finally {
      postStateChange();
    }
  }
 public void setObject(ExecutionContext ec, PreparedStatement ps, int[] exprIndex, Object value) {
   if (value == null) {
     getDatastoreMapping(0).setObject(ps, exprIndex[0], null);
   } else if (datastoreMappings != null
       && datastoreMappings.length > 0
       && datastoreMappings[0].isStringBased()) {
     TypeConverter conv =
         ec.getNucleusContext()
             .getTypeManager()
             .getTypeConverterForType(LocalTime.class, String.class);
     if (conv != null) {
       Object obj = conv.toDatastoreType(value);
       getDatastoreMapping(0).setObject(ps, exprIndex[0], obj);
     } else {
       throw new NucleusUserException("This type doesn't support persistence as a String");
     }
   } else {
     LocalTime val = (LocalTime) value;
     Calendar cal = Calendar.getInstance();
     cal.set(0, 0, 0, val.getHour(), val.getMinute(), val.getSecond());
     getDatastoreMapping(0).setObject(ps, exprIndex[0], cal);
   }
 }
  /*
   * (non-Javadoc)
   * @see org.datanucleus.store.mapping.JavaTypeMapping#getObject(org.datanucleus.ExecutionContext, java.lang.Object, int[])
   */
  public Object getObject(ExecutionContext ec, ResultSet resultSet, int[] exprIndex) {
    try {
      // Check for null entries
      if (getDatastoreMapping(0).getObject(resultSet, exprIndex[0]) == null) {
        return null;
      }
    } catch (Exception e) {
      // Do nothing
    }

    if (singleColumn) {
      Timestamp ts = (Timestamp) getDatastoreMapping(0).getObject(resultSet, exprIndex[0]);
      GregorianCalendar cal = new GregorianCalendar();
      cal.setTimeInMillis(ts.getTime());

      String timezoneID =
          ec.getNucleusContext()
              .getPersistenceConfiguration()
              .getStringProperty("datanucleus.ServerTimeZoneID");
      if (timezoneID != null) {
        // Apply server timezone ID since we dont know what it was upon persistence
        cal.setTimeZone(TimeZone.getTimeZone(timezoneID));
      }
      return cal;
    } else {
      // (Timestamp millisecs, Timezone) implementation
      long millisecs = getDatastoreMapping(0).getLong(resultSet, exprIndex[0]);

      GregorianCalendar cal = new GregorianCalendar();
      cal.setTime(new Date(millisecs));
      String timezoneId = getDatastoreMapping(1).getString(resultSet, exprIndex[1]);
      if (timezoneId != null) {
        cal.setTimeZone(TimeZone.getTimeZone(timezoneId));
      }
      return cal;
    }
  }
예제 #9
0
  /**
   * Method to initialise the SCO from an existing value.
   *
   * @param m The object to set from
   * @param forInsert Whether the object needs inserting in the datastore with this value
   * @param forUpdate Whether to update the datastore with this value
   */
  public synchronized void initialise(java.util.Map m, boolean forInsert, boolean forUpdate) {
    if (m != null) {
      // Check for the case of serialised maps, and assign ObjectProviders to any PC keys/values
      // without
      if (SCOUtils.mapHasSerialisedKeysAndValues(ownerMmd)
          && (ownerMmd.getMap().keyIsPersistent() || ownerMmd.getMap().valueIsPersistent())) {
        ExecutionContext ec = ownerOP.getExecutionContext();
        Iterator iter = m.entrySet().iterator();
        while (iter.hasNext()) {
          Map.Entry entry = (Map.Entry) iter.next();
          Object key = entry.getKey();
          Object value = entry.getValue();
          if (ownerMmd.getMap().keyIsPersistent()) {
            ObjectProvider objSM = ec.findObjectProvider(key);
            if (objSM == null) {
              objSM =
                  ec.getNucleusContext()
                      .getObjectProviderFactory()
                      .newForEmbedded(ec, key, false, ownerOP, ownerMmd.getAbsoluteFieldNumber());
            }
          }
          if (ownerMmd.getMap().valueIsPersistent()) {
            ObjectProvider objSM = ec.findObjectProvider(value);
            if (objSM == null) {
              objSM =
                  ec.getNucleusContext()
                      .getObjectProviderFactory()
                      .newForEmbedded(ec, value, false, ownerOP, ownerMmd.getAbsoluteFieldNumber());
            }
          }
        }
      }

      if (backingStore != null && useCache && !isCacheLoaded) {
        // Mark as loaded
        isCacheLoaded = true;
      }

      if (forInsert) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              Localiser.msg(
                  "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + m.size()));
        }

        makeDirty();
        if (useCache) {
          // Make sure we have all values loaded (e.g if in optimistic tx and we put new entry)
          loadFromStore();
        }
        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(ownerOP)) {
            Iterator iter = m.entrySet().iterator();
            while (iter.hasNext()) {
              Map.Entry entry = (Map.Entry) iter.next();
              ownerOP
                  .getExecutionContext()
                  .addOperationToQueue(
                      new MapPutOperation(ownerOP, backingStore, entry.getKey(), entry.getValue()));
            }
          } else {
            backingStore.putAll(ownerOP, m);
          }
        }
        delegate.putAll(m);
      } else if (forUpdate) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              Localiser.msg(
                  "023008", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + m.size()));
        }

        // TODO This is clear+putAll. Improve it to work out what is changed
        delegate.clear();
        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(ownerOP)) {
            // If not yet flushed to store then no need to add to queue (since will be handled via
            // insert)
            if (ownerOP.isFlushedToDatastore() || !ownerOP.getLifecycleState().isNew()) {
              ownerOP
                  .getExecutionContext()
                  .addOperationToQueue(new MapClearOperation(ownerOP, backingStore));
            }
          } else {
            backingStore.clear(ownerOP);
          }
        }
        if (useCache) {
          // Make sure we have all values loaded (e.g if in optimistic tx and we put new entry)
          loadFromStore();
        }

        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(ownerOP)) {
            // If not yet flushed to store then no need to add to queue (since will be handled via
            // insert)
            if (ownerOP.isFlushedToDatastore() || !ownerOP.getLifecycleState().isNew()) {
              Iterator iter = m.entrySet().iterator();
              while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                ownerOP
                    .getExecutionContext()
                    .addOperationToQueue(
                        new MapPutOperation(
                            ownerOP, backingStore, entry.getKey(), entry.getValue()));
              }
            }
          } else {
            backingStore.putAll(ownerOP, m);
          }
        }
        delegate.putAll(m);
        makeDirty();
      } else {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              Localiser.msg(
                  "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + m.size()));
        }
        delegate.clear();
        delegate.putAll(m);
      }
    }
  }
  protected static Object getObjectUsingDatastoreIdForResult(
      final Result result,
      final AbstractClassMetaData cmd,
      final ExecutionContext ec,
      boolean ignoreCache,
      final int[] fpMembers,
      String tableName,
      StoreManager storeMgr,
      Table table) {
    if (cmd.hasDiscriminatorStrategy()) {
      // Check the class for this discriminator value
      String familyName = HBaseUtils.getFamilyNameForColumn(table.getDiscriminatorColumn());
      String columnName = HBaseUtils.getQualifierNameForColumn(table.getDiscriminatorColumn());
      Object discValue = new String(result.getValue(familyName.getBytes(), columnName.getBytes()));
      if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.CLASS_NAME
          && !cmd.getFullClassName().equals(discValue)) {
        return null;
      } else if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.VALUE_MAP
          && !cmd.getDiscriminatorValue().equals(discValue)) {
        return null;
      }
    }

    String dsidFamilyName = HBaseUtils.getFamilyNameForColumn(table.getDatastoreIdColumn());
    String dsidColumnName = HBaseUtils.getQualifierNameForColumn(table.getDatastoreIdColumn());
    Object id = null;
    try {
      byte[] bytes = result.getValue(dsidFamilyName.getBytes(), dsidColumnName.getBytes());
      if (bytes != null) {
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        Object key = ois.readObject();
        id =
            ec.getNucleusContext().getIdentityManager().getDatastoreId(cmd.getFullClassName(), key);
        ois.close();
        bis.close();
      } else {
        throw new NucleusException(
            "Retrieved identity for family="
                + dsidFamilyName
                + " column="
                + dsidColumnName
                + " IS NULL");
      }
    } catch (Exception e) {
      throw new NucleusException(e.getMessage(), e);
    }

    final FieldManager fm = new FetchFieldManager(ec, cmd, result, table);
    Object pc =
        ec.findObject(
            id,
            new FieldValues() {
              // ObjectProvider calls the fetchFields method
              public void fetchFields(ObjectProvider op) {
                op.replaceFields(fpMembers, fm);
              }

              public void fetchNonLoadedFields(ObjectProvider op) {
                op.replaceNonLoadedFields(fpMembers, fm);
              }

              public FetchPlan getFetchPlanForLoading() {
                return null;
              }
            },
            null,
            ignoreCache,
            false);

    if (cmd.isVersioned()) {
      // Set the version on the object
      ObjectProvider op = ec.findObjectProvider(pc);
      Object version = null;
      VersionMetaData vermd = cmd.getVersionMetaDataForClass();
      if (vermd.getFieldName() != null) {
        // Set the version from the field value
        AbstractMemberMetaData verMmd = cmd.getMetaDataForMember(vermd.getFieldName());
        version = op.provideField(verMmd.getAbsoluteFieldNumber());
      } else {
        // Get the surrogate version from the datastore
        version = HBaseUtils.getSurrogateVersionForObject(cmd, result, tableName, storeMgr);
      }
      op.setVersion(version);
    }

    if (result.getRow() != null) {
      ObjectProvider sm = ec.findObjectProvider(pc);
      sm.setAssociatedValue("HBASE_ROW_KEY", result.getRow());
    }

    return pc;
  }
 public StoreManager getStoreManager() {
   return (myEC.getNucleusContext().isFederated()
       ? ((FederatedStoreManager) myEC.getStoreManager()).getStoreManagerForClass(cmd)
       : myEC.getStoreManager());
 }
예제 #12
0
  /**
   * Method to initialise the SCO from an existing value.
   *
   * @param c The object to set from
   * @param forInsert Whether the object needs inserting in the datastore with this value
   * @param forUpdate Whether to update the SCO in the datastore with this value
   */
  public void initialise(java.util.ArrayList c, boolean forInsert, boolean forUpdate) {
    if (c != null) {
      // Check for the case of serialised PC elements, and assign ObjectProviders to the elements
      // without
      if (SCOUtils.collectionHasSerialisedElements(ownerMmd)
          && ownerMmd.getCollection().elementIsPersistent()) {
        ExecutionContext ec = ownerOP.getExecutionContext();
        Iterator iter = c.iterator();
        while (iter.hasNext()) {
          Object pc = iter.next();
          ObjectProvider objOP = ec.findObjectProvider(pc);
          if (objOP == null) {
            objOP =
                ec.getNucleusContext()
                    .getObjectProviderFactory()
                    .newForEmbedded(ec, pc, false, ownerOP, ownerMmd.getAbsoluteFieldNumber());
          }
        }
      }

      if (backingStore != null && useCache && !isCacheLoaded) {
        // Mark as loaded so we just use the value
        isCacheLoaded = true;
      }

      if (forInsert) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              Localiser.msg(
                  "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size()));
        }
        if (useCache) {
          loadFromStore();
        }
        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
            for (Object element : c) {
              ownerOP
                  .getExecutionContext()
                  .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element));
            }
          } else {
            try {
              backingStore.addAll(ownerOP, c, (useCache ? delegate.size() : -1));
            } catch (NucleusDataStoreException dse) {
              NucleusLogger.PERSISTENCE.warn(
                  Localiser.msg("023013", "addAll", ownerMmd.getName(), dse));
            }
          }
        }
        makeDirty();
        delegate.addAll(c);
      } else if (forUpdate) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              Localiser.msg(
                  "023008", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size()));
        }

        // TODO This does clear+addAll : Improve this and work out which elements are added and
        // which deleted
        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
            ownerOP
                .getExecutionContext()
                .addOperationToQueue(new CollectionClearOperation(ownerOP, backingStore));
          } else {
            backingStore.clear(ownerOP);
          }
        }

        if (useCache) {
          loadFromStore();
        }
        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
            for (Object element : c) {
              ownerOP
                  .getExecutionContext()
                  .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element));
            }
          } else {
            try {
              backingStore.addAll(ownerOP, c, (useCache ? delegate.size() : -1));
            } catch (NucleusDataStoreException dse) {
              NucleusLogger.PERSISTENCE.warn(
                  Localiser.msg("023013", "addAll", ownerMmd.getName(), dse));
            }
          }
        }
        delegate.addAll(c);
        makeDirty();
      } else {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              Localiser.msg(
                  "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size()));
        }
        delegate.clear();
        delegate.addAll(c);
      }
    }
  }