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; } }
/** * 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()); }
/** * 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); } } }