Search in sources :

Example 36 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method getObjectFromLevel2CacheForUnique.

/**
 * Convenience method to access the identity that corresponds to a unique key, in the Level 2 cache.
 * @param uniKey The CacheUniqueKey to use in lookups
 * @return Identity of the associated object
 */
protected Object getObjectFromLevel2CacheForUnique(CacheUniqueKey uniKey) {
    Object pc = null;
    if (l2CacheEnabled) {
        String cacheRetrieveMode = getLevel2CacheRetrieveMode();
        if ("bypass".equalsIgnoreCase(cacheRetrieveMode)) {
            // Cache retrieval currently turned off
            return null;
        }
        Level2Cache l2Cache = nucCtx.getLevel2Cache();
        CachedPC cachedPC = l2Cache.getUnique(uniKey);
        if (cachedPC != null) {
            Object id = cachedPC.getId();
            // Create active version of cached object with ObjectProvider connected and same id
            ObjectProvider op = nucCtx.getObjectProviderFactory().newForCachedPC(this, id, cachedPC);
            // Object in P_CLEAN state
            pc = op.getObject();
            if (NucleusLogger.CACHE.isDebugEnabled()) {
                NucleusLogger.CACHE.debug(Localiser.msg("004006", IdentityUtils.getPersistableIdentityForId(id), StringUtils.intArrayToString(cachedPC.getLoadedFieldNumbers()), cachedPC.getVersion(), StringUtils.toJVMIDString(pc)));
            }
            if (tx.isActive() && tx.getOptimistic()) {
                // Optimistic txns, so return as P_NONTRANS (as per JDO spec)
                op.makeNontransactional();
            } else if (!tx.isActive() && getApiAdapter().isTransactional(pc)) {
                // Non-tx context, so return as P_NONTRANS (as per JDO spec)
                op.makeNontransactional();
            }
            return pc;
        }
        if (NucleusLogger.CACHE.isDebugEnabled()) {
            NucleusLogger.CACHE.debug(Localiser.msg("004005", uniKey));
        }
    }
    return null;
}
Also used : Level2Cache(org.datanucleus.cache.Level2Cache) CachedPC(org.datanucleus.cache.CachedPC) ObjectProvider(org.datanucleus.state.ObjectProvider)

Example 37 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method deleteObjectWork.

/**
 * Method to delete an object from the datastore.
 * NOT to be called by internal methods. Only callable by external APIs (JDO/JPA).
 * @param obj The object
 */
void deleteObjectWork(Object obj) {
    ObjectProvider op = findObjectProvider(obj);
    if (op == null && getApiAdapter().isDetached(obj)) {
        // Delete of detached, so find a managed attached version and delete that
        Object attachedObj = findObject(getApiAdapter().getIdForObject(obj), true, false, obj.getClass().getName());
        op = findObjectProvider(attachedObj);
    }
    if (op != null) {
        // Add the object to the relevant list of dirty ObjectProviders
        if (indirectDirtyOPs.contains(op)) {
            // Object is dirty indirectly, but now user-requested so move to direct list of dirty objects
            indirectDirtyOPs.remove(op);
            dirtyOPs.add(op);
        } else if (!dirtyOPs.contains(op)) {
            dirtyOPs.add(op);
            if (l2CacheTxIds != null && nucCtx.isClassCacheable(op.getClassMetaData())) {
                l2CacheTxIds.add(op.getInternalObjectId());
            }
        }
    }
    // Delete the object
    deleteObjectInternal(obj);
    if (pbrAtCommitHandler != null && tx.isActive()) {
        if (op != null) {
            if (getApiAdapter().isDeleted(obj)) {
                pbrAtCommitHandler.addDeletedObject(op.getInternalObjectId());
            }
        }
    }
}
Also used : ObjectProvider(org.datanucleus.state.ObjectProvider)

Example 38 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method getManagedObjects.

/**
 * Accessor for the currently managed objects for the current transaction.
 * If the transaction is not active this returns null.
 * @param states States that we want the enlisted objects for
 * @param classes Classes that we want the enlisted objects for
 * @return Collection of managed objects enlisted in the current transaction
 */
public Set getManagedObjects(String[] states, Class[] classes) {
    if (!tx.isActive()) {
        return null;
    }
    Set objs = new HashSet();
    for (ObjectProvider op : enlistedOPCache.values()) {
        boolean matches = false;
        for (int i = 0; i < states.length; i++) {
            if (getApiAdapter().getObjectState(op.getObject()).equals(states[i])) {
                for (int j = 0; j < classes.length; j++) {
                    if (classes[j] == op.getObject().getClass()) {
                        matches = true;
                        objs.add(op.getObject());
                        break;
                    }
                }
            }
            if (matches) {
                break;
            }
        }
    }
    return objs;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) BitSet(java.util.BitSet) ObjectProvider(org.datanucleus.state.ObjectProvider) HashSet(java.util.HashSet)

Example 39 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method getObjectsFromLevel2Cache.

/**
 * Convenience method to access a collection of objects from the Level 2 cache.
 * @param ids Collection of ids to retrieve
 * @return Map of persistable objects (with connected ObjectProvider) keyed by their id if found in the L2 cache
 */
protected Map getObjectsFromLevel2Cache(Collection ids) {
    if (l2CacheEnabled) {
        // TODO Restrict to only those ids that are cacheable
        Level2Cache l2Cache = nucCtx.getLevel2Cache();
        Map<Object, CachedPC> cachedPCs = l2Cache.getAll(ids);
        Map pcsById = new HashMap(cachedPCs.size());
        for (Map.Entry<Object, CachedPC> entry : cachedPCs.entrySet()) {
            Object id = entry.getKey();
            CachedPC cachedPC = entry.getValue();
            if (cachedPC != null) {
                // Create active version of cached object with ObjectProvider connected and same id
                ObjectProvider op = nucCtx.getObjectProviderFactory().newForCachedPC(this, id, cachedPC);
                // Object in P_CLEAN state
                Object pc = op.getObject();
                if (NucleusLogger.CACHE.isDebugEnabled()) {
                    NucleusLogger.CACHE.debug(Localiser.msg("004006", IdentityUtils.getPersistableIdentityForId(id), StringUtils.intArrayToString(cachedPC.getLoadedFieldNumbers()), cachedPC.getVersion(), StringUtils.toJVMIDString(pc)));
                }
                if (tx.isActive() && tx.getOptimistic()) {
                    // Optimistic txns, so return as P_NONTRANS (as per JDO spec)
                    op.makeNontransactional();
                } else if (!tx.isActive() && getApiAdapter().isTransactional(pc)) {
                    // Non-tx context, so return as P_NONTRANS (as per JDO spec)
                    op.makeNontransactional();
                }
                pcsById.put(id, pc);
            } else {
                if (NucleusLogger.CACHE.isDebugEnabled()) {
                    NucleusLogger.CACHE.debug(Localiser.msg("004005", IdentityUtils.getPersistableIdentityForId(id)));
                }
            }
        }
        return pcsById;
    }
    return null;
}
Also used : Level2Cache(org.datanucleus.cache.Level2Cache) ConcurrentReferenceHashMap(org.datanucleus.util.ConcurrentReferenceHashMap) HashMap(java.util.HashMap) CachedPC(org.datanucleus.cache.CachedPC) ObjectProvider(org.datanucleus.state.ObjectProvider) ConcurrentReferenceHashMap(org.datanucleus.util.ConcurrentReferenceHashMap) Map(java.util.Map) HashMap(java.util.HashMap)

Example 40 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method performLevel2CacheUpdateAtCommit.

/**
 * Method invoked during commit() to perform updates to the L2 cache.
 * <ul>
 * <li>Any objects modified during the current transaction will be added/updated in the L2 cache.</li>
 * <li>Any objects that aren't modified but have been enlisted will be added to the L2 cache.</li>
 * <li>Any objects that are modified but no longer enlisted (due to garbage collection) will be
 * removed from the L2 cache (to avoid giving out old data).</li>
 * </ul>
 */
private void performLevel2CacheUpdateAtCommit() {
    if (l2CacheTxIds == null) {
        return;
    }
    String cacheStoreMode = getLevel2CacheStoreMode();
    if ("bypass".equalsIgnoreCase(cacheStoreMode)) {
        // L2 cache storage turned off right now
        return;
    }
    // Process all modified objects adding/updating/removing from L2 cache as appropriate
    Set<ObjectProvider> opsToCache = null;
    Set<Object> idsToRemove = null;
    for (Object id : l2CacheTxIds) {
        ObjectProvider op = enlistedOPCache.get(id);
        if (op == null) {
            // Modified object either no longer enlisted (GCed) OR is an embedded object without own identity. Remove from L2 if present
            if (NucleusLogger.CACHE.isDebugEnabled()) {
                if (nucCtx.getLevel2Cache().containsOid(id)) {
                    NucleusLogger.CACHE.debug(Localiser.msg("004014", id));
                }
            }
            if (idsToRemove == null) {
                idsToRemove = new HashSet<Object>();
            }
            idsToRemove.add(id);
        } else {
            // Modified object still enlisted so cacheable
            Object obj = op.getObject();
            Object objID = getApiAdapter().getIdForObject(obj);
            if (objID == null || objID instanceof IdentityReference) {
            // Must be embedded
            } else if (getApiAdapter().isDeleted(obj)) {
                // Object has been deleted so remove from L2 cache
                if (NucleusLogger.CACHE.isDebugEnabled()) {
                    NucleusLogger.CACHE.debug(Localiser.msg("004007", StringUtils.toJVMIDString(obj), op.getInternalObjectId()));
                }
                if (idsToRemove == null) {
                    idsToRemove = new HashSet<Object>();
                }
                idsToRemove.add(objID);
            } else if (!getApiAdapter().isDetached(obj)) {
                // Object has been added/modified so update in L2 cache
                if (opsToCache == null) {
                    opsToCache = new HashSet<>();
                }
                opsToCache.add(op);
                if (l2CacheObjectsToEvictUponRollback == null) {
                    l2CacheObjectsToEvictUponRollback = new LinkedList<Object>();
                }
                l2CacheObjectsToEvictUponRollback.add(id);
            }
        }
    }
    if (idsToRemove != null && !idsToRemove.isEmpty()) {
        // Bulk evict from L2 cache
        nucCtx.getLevel2Cache().evictAll(idsToRemove);
    }
    if (opsToCache != null && !opsToCache.isEmpty()) {
        // Bulk put into L2 cache of required ObjectProviders
        putObjectsIntoLevel2Cache(opsToCache);
    }
    l2CacheTxIds.clear();
    l2CacheTxFieldsToUpdateById.clear();
}
Also used : IdentityReference(org.datanucleus.identity.IdentityReference) ObjectProvider(org.datanucleus.state.ObjectProvider) HashSet(java.util.HashSet)

Aggregations

ObjectProvider (org.datanucleus.state.ObjectProvider)160 ExecutionContext (org.datanucleus.ExecutionContext)85 Iterator (java.util.Iterator)43 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)34 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)25 Map (java.util.Map)22 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)22 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)21 SQLException (java.sql.SQLException)17 Collection (java.util.Collection)16 ApiAdapter (org.datanucleus.api.ApiAdapter)16 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)16 SCOCollectionIterator (org.datanucleus.store.types.SCOCollectionIterator)16 ArrayList (java.util.ArrayList)14 HashSet (java.util.HashSet)14 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)14 NucleusException (org.datanucleus.exceptions.NucleusException)13 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)13 ListIterator (java.util.ListIterator)12 SQLController (org.datanucleus.store.rdbms.SQLController)12