Search in sources :

Example 1 with MapStore

use of org.datanucleus.store.types.scostore.MapStore in project datanucleus-rdbms by datanucleus.

the class MapMapping method postUpdate.

/**
 * Method to be called after any update of the owner class element.
 * @param ownerOP ObjectProvider of the owner
 */
public void postUpdate(ObjectProvider ownerOP) {
    ExecutionContext ec = ownerOP.getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    java.util.Map value = (java.util.Map) ownerOP.provideField(getAbsoluteFieldNumber());
    if (containerIsStoredInSingleColumn()) {
        // Do nothing when serialised since we are handled in the main request
        if (value != null) {
            if (mmd.getMap().keyIsPersistent() || mmd.getMap().valueIsPersistent()) {
                // Make sure all persistable keys/values have ObjectProviders
                Set entries = value.entrySet();
                Iterator iter = entries.iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    if (mmd.getMap().keyIsPersistent() && entry.getKey() != null) {
                        Object key = entry.getKey();
                        if (ec.findObjectProvider(key) == null || ec.getApiAdapter().getExecutionContext(key) == null) {
                            ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, key, false, ownerOP, mmd.getAbsoluteFieldNumber());
                        }
                    }
                    if (mmd.getMap().valueIsPersistent() && entry.getValue() != null) {
                        Object val = entry.getValue();
                        if (ec.findObjectProvider(val) == null || ec.getApiAdapter().getExecutionContext(val) == null) {
                            ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, val, false, ownerOP, mmd.getAbsoluteFieldNumber());
                        }
                    }
                }
            }
        }
        return;
    }
    if (value == null) {
        // remove any entries in the map and replace it with an empty SCO wrapper
        ((MapStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null)).clear(ownerOP);
        replaceFieldWithWrapper(ownerOP, null);
        return;
    }
    if (value instanceof BackedSCO) {
        // Already have a SCO value, so flush outstanding updates
        ownerOP.getExecutionContext().flushOperationsForBackingStore(((BackedSCO) value).getBackingStore(), ownerOP);
        return;
    }
    if (mmd.isCascadeUpdate()) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("007009", mmd.getFullFieldName()));
        }
        // Update the datastore with this value of map (clear old entries and add new ones)
        // This method could be called in two situations
        // 1). Update a map field of an object, so UpdateRequest is called, which calls here
        // 2). Persist a new object, and it needed to wait til the element was inserted so
        // goes into dirty state and then flush() triggers UpdateRequest, which comes here
        MapStore store = ((MapStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, value.getClass()));
        // TODO Consider making this more efficient picking the ones to remove/add
        // e.g use an update() method on the backing store like for CollectionStore
        store.clear(ownerOP);
        store.putAll(ownerOP, value);
        // Replace the field with a wrapper containing these entries
        replaceFieldWithWrapper(ownerOP, value);
    } else {
        // User doesnt want to update by reachability
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("007008", mmd.getFullFieldName()));
        }
        return;
    }
}
Also used : Set(java.util.Set) BackedSCO(org.datanucleus.store.types.wrappers.backed.BackedSCO) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) ExecutionContext(org.datanucleus.ExecutionContext) Map(java.util.Map) Iterator(java.util.Iterator) MapStore(org.datanucleus.store.types.scostore.MapStore) Map(java.util.Map)

Example 2 with MapStore

use of org.datanucleus.store.types.scostore.MapStore in project datanucleus-rdbms by datanucleus.

the class MapMapping method postInsert.

/**
 * Method to be called after the insert of the owner class element.
 * @param ownerOP ObjectProvider of the owner
 */
public void postInsert(ObjectProvider ownerOP) {
    ExecutionContext ec = ownerOP.getExecutionContext();
    java.util.Map value = (java.util.Map) ownerOP.provideField(getAbsoluteFieldNumber());
    if (containerIsStoredInSingleColumn()) {
        // Do nothing when serialised since we are handled in the main request
        if (value != null) {
            if (mmd.getMap().keyIsPersistent() || mmd.getMap().valueIsPersistent()) {
                // Make sure all persistable keys/values have ObjectProviders
                Set entries = value.entrySet();
                Iterator iter = entries.iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    if (mmd.getMap().keyIsPersistent() && entry.getKey() != null) {
                        Object key = entry.getKey();
                        if (ec.findObjectProvider(key) == null || ec.getApiAdapter().getExecutionContext(key) == null) {
                            ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, key, false, ownerOP, mmd.getAbsoluteFieldNumber());
                        }
                    }
                    if (mmd.getMap().valueIsPersistent() && entry.getValue() != null) {
                        Object val = entry.getValue();
                        if (ec.findObjectProvider(val) == null || ec.getApiAdapter().getExecutionContext(val) == null) {
                            ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, val, false, ownerOP, mmd.getAbsoluteFieldNumber());
                        }
                    }
                }
            }
        }
        return;
    }
    if (value == null) {
        // replace null map with an empty SCO wrapper
        replaceFieldWithWrapper(ownerOP, null);
        return;
    }
    if (!mmd.isCascadePersist()) {
        // Check that all keys/values are persistent before continuing and throw exception if necessary
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("007006", mmd.getFullFieldName()));
        }
        ApiAdapter api = ec.getApiAdapter();
        Set entries = value.entrySet();
        Iterator iter = entries.iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            if (api.isPersistable(entry.getKey())) {
                if (!api.isPersistent(entry.getKey()) && !api.isDetached(entry.getKey())) {
                    // Key is not persistent so throw exception
                    throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), entry.getKey());
                }
            }
            if (api.isPersistable(entry.getValue())) {
                if (!api.isPersistent(entry.getValue()) && !api.isDetached(entry.getValue())) {
                    // Value is not persistent so throw exception
                    throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), entry.getValue());
                }
            }
        }
    } else {
        // Reachability
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("007007", mmd.getFullFieldName()));
        }
    }
    if (value.size() > 0) {
        // Add the entries direct to the datastore
        ((MapStore) table.getStoreManager().getBackingStoreForField(ownerOP.getExecutionContext().getClassLoaderResolver(), mmd, value.getClass())).putAll(ownerOP, value);
        // Create a SCO wrapper with the entries loaded
        replaceFieldWithWrapper(ownerOP, value);
    } else {
        if (mmd.getRelationType(ownerOP.getExecutionContext().getClassLoaderResolver()) == RelationType.MANY_TO_MANY_BI) {
            // Create a SCO wrapper, pass in null so it loads any from the datastore (on other side?)
            replaceFieldWithWrapper(ownerOP, null);
        } else {
            // Create a SCO wrapper, pass in empty map to avoid loading from DB (extra SQL)
            replaceFieldWithWrapper(ownerOP, value);
        }
    }
}
Also used : Set(java.util.Set) ApiAdapter(org.datanucleus.api.ApiAdapter) ReachableObjectNotCascadedException(org.datanucleus.exceptions.ReachableObjectNotCascadedException) ExecutionContext(org.datanucleus.ExecutionContext) Map(java.util.Map) Iterator(java.util.Iterator) MapStore(org.datanucleus.store.types.scostore.MapStore) Map(java.util.Map)

Aggregations

Iterator (java.util.Iterator)2 Map (java.util.Map)2 Set (java.util.Set)2 ExecutionContext (org.datanucleus.ExecutionContext)2 MapStore (org.datanucleus.store.types.scostore.MapStore)2 ApiAdapter (org.datanucleus.api.ApiAdapter)1 ReachableObjectNotCascadedException (org.datanucleus.exceptions.ReachableObjectNotCascadedException)1 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)1 BackedSCO (org.datanucleus.store.types.wrappers.backed.BackedSCO)1