/** * Constructor, using the ObjectProvider of the "owner" and the field name. * * @param op The owner ObjectProvider * @param mmd Metadata for the member */ public Map(ObjectProvider op, AbstractMemberMetaData mmd) { super(op, mmd); // Set up our "delegate" this.delegate = new java.util.HashMap(); ExecutionContext ec = ownerOP.getExecutionContext(); allowNulls = SCOUtils.allowNullsInContainer(allowNulls, mmd); useCache = SCOUtils.useContainerCache(ownerOP, mmd); if (!SCOUtils.mapHasSerialisedKeysAndValues(mmd) && mmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) { ClassLoaderResolver clr = ec.getClassLoaderResolver(); this.backingStore = (MapStore) ((BackedSCOStoreManager) ownerOP.getStoreManager()) .getBackingStoreForField(clr, mmd, java.util.Map.class); } if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( SCOUtils.getContainerInfoMessage( ownerOP, ownerMmd.getName(), this, useCache, allowNulls, SCOUtils.useCachedLazyLoading(ownerOP, ownerMmd))); } }
/** * 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); } } }