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;
}
Aggregations