Search in sources :

Example 1 with StorePersistenceHandler

use of org.datanucleus.store.StorePersistenceHandler in project datanucleus-core by datanucleus.

the class FlushNonReferential method flushDeleteInsertUpdateGrouped.

/**
 * Method that does the flushing of the passed ObjectProviders, grouping them into all DELETEs, then all INSERTs,
 * finally all UPDATEs. The StorePersistenceHandler will get calls to <i>deleteObjects</i>, <i>insertObjects</i>
 * and <i>updateObject</i> (for each other one). Note that this is in a separate method to allow calls by
 * other FlushProcesses that want to take advantage of the basic flush method without
 * @param opsToFlush The ObjectProviders to process
 * @param ec ExecutionContext
 * @return Any optimistic verification exceptions thrown during flush
 */
public List<NucleusOptimisticException> flushDeleteInsertUpdateGrouped(Set<ObjectProvider> opsToFlush, ExecutionContext ec) {
    List<NucleusOptimisticException> optimisticFailures = null;
    Set<Class> classesToFlush = null;
    if (ec.getNucleusContext().getStoreManager().getQueryManager().getQueryResultsCache() != null) {
        classesToFlush = new HashSet();
    }
    Set<ObjectProvider> opsToDelete = new HashSet<ObjectProvider>();
    Set<ObjectProvider> opsToInsert = new HashSet<ObjectProvider>();
    Iterator<ObjectProvider> opIter = opsToFlush.iterator();
    while (opIter.hasNext()) {
        ObjectProvider op = opIter.next();
        if (op.isEmbedded()) {
            // Embedded have nothing to flush since the owner manages it
            op.markAsFlushed();
            opIter.remove();
        } else {
            if (classesToFlush != null && op.getObject() != null) {
                classesToFlush.add(op.getObject().getClass());
            }
            if (op.getLifecycleState().isNew() && !op.isFlushedToDatastore() && !op.isFlushedNew()) {
                // P_NEW and not yet flushed to datastore
                opsToInsert.add(op);
                opIter.remove();
            } else if (op.getLifecycleState().isDeleted() && !op.isFlushedToDatastore()) {
                if (!op.getLifecycleState().isNew()) {
                    // P_DELETED
                    opsToDelete.add(op);
                    opIter.remove();
                } else if (op.getLifecycleState().isNew() && op.isFlushedNew()) {
                    // P_NEW_DELETED already persisted
                    opsToDelete.add(op);
                    opIter.remove();
                }
            }
        }
    }
    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        NucleusLogger.PERSISTENCE.debug(Localiser.msg("010046", opsToDelete.size(), opsToInsert.size(), opsToFlush.size()));
    }
    StorePersistenceHandler persistenceHandler = ec.getStoreManager().getPersistenceHandler();
    if (!opsToDelete.isEmpty()) {
        // TODO This omits some parts of sm.internalDeletePersistent
        for (ObjectProvider op : opsToDelete) {
            op.setFlushing(true);
            ec.getCallbackHandler().preDelete(op.getObject());
        }
        try {
            persistenceHandler.deleteObjects(opsToDelete.toArray(new ObjectProvider[opsToDelete.size()]));
        } catch (NucleusOptimisticException noe) {
            optimisticFailures = new ArrayList();
            Throwable[] nestedExcs = noe.getNestedExceptions();
            if (nestedExcs != null && nestedExcs.length > 1) {
                NucleusOptimisticException[] noes = (NucleusOptimisticException[]) nestedExcs;
                for (int i = 0; i < nestedExcs.length; i++) {
                    optimisticFailures.add(noes[i]);
                }
            } else {
                optimisticFailures.add(noe);
            }
        }
        for (ObjectProvider op : opsToDelete) {
            ec.getCallbackHandler().postDelete(op.getObject());
            op.setFlushedNew(false);
            op.markAsFlushed();
            op.setFlushing(false);
        }
    }
    if (!opsToInsert.isEmpty()) {
        // TODO This omits some parts of sm.internalMakePersistent
        for (ObjectProvider op : opsToInsert) {
            op.setFlushing(true);
            ec.getCallbackHandler().preStore(op.getObject());
        // TODO Make sure identity is set since user could have updated fields in preStore
        }
        persistenceHandler.insertObjects(opsToInsert.toArray(new ObjectProvider[opsToInsert.size()]));
        for (ObjectProvider op : opsToInsert) {
            ec.getCallbackHandler().postStore(op.getObject());
            op.setFlushedNew(true);
            op.markAsFlushed();
            op.setFlushing(false);
            // Update the object in the cache(s) now that version/id are set
            ec.putObjectIntoLevel1Cache(op);
        }
    }
    if (!opsToFlush.isEmpty()) {
        // Objects to update
        for (ObjectProvider op : opsToFlush) {
            try {
                op.flush();
            } catch (NucleusOptimisticException oe) {
                if (optimisticFailures == null) {
                    optimisticFailures = new ArrayList();
                }
                optimisticFailures.add(oe);
            }
        }
    }
    if (classesToFlush != null) {
        // Flush any query results from cache for these types
        Iterator<Class> queryClsIter = classesToFlush.iterator();
        while (queryClsIter.hasNext()) {
            Class cls = queryClsIter.next();
            ec.getNucleusContext().getStoreManager().getQueryManager().evictQueryResultsForType(cls);
        }
    }
    return optimisticFailures;
}
Also used : NucleusOptimisticException(org.datanucleus.exceptions.NucleusOptimisticException) ArrayList(java.util.ArrayList) ObjectProvider(org.datanucleus.state.ObjectProvider) StorePersistenceHandler(org.datanucleus.store.StorePersistenceHandler) HashSet(java.util.HashSet)

Aggregations

ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 NucleusOptimisticException (org.datanucleus.exceptions.NucleusOptimisticException)1 ObjectProvider (org.datanucleus.state.ObjectProvider)1 StorePersistenceHandler (org.datanucleus.store.StorePersistenceHandler)1