I'm looking for a way to return the UnitOfWork to a clean state without having the clear the whole thing. I still want to have access to the entities I've loaded. This is the base of what I have, but I'm not sure if this is going to break doctrine in weird ways.
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();//Can this be called once here, or should it be called in the inside loop so we get fresh information after a potential cascading refresh or persist?
foreach ($uow->getIdentityMap() as $className => $entities) {
foreach ($entities as $oid => $entity) {
if ($uow->isEntityScheduled($entity)) {
if ($uow->isScheduledForInsert($entity)) {
$uow->scheduleForDelete($entity);//Removes from the insert list without cascading delete or calling removal events
} elseif ($uow->isScheduledForUpdate($entity)) {
$em->refresh($entity);
} elseif ($uow->isScheduledForDelete($entity)) {
$em->persist($entity);
$em->refresh($entity);//Should I re-call computeChangeSets() here so I can check if the entity is now scheduled for update?
}
}
}
}
For context: I am running a batch operation where I persist any needed changes after each record is processed. If one record fails due to a bug, that failure is handled, but it can break the rest of the batch with this type of exception:
A new entity was found through the relationship FOO#bar that was not configured to cascade persist operations for entity: otherFooBar .
Since I don't need to save any changes from processing a record if it fails, I'd like to simply clean up all changes and keep the object graph intact while continuing to process the batch.
I've read through the doctrine source and it seem like this should work correctly, but I am not intimately familiar with Doctrine's internals. Does anyone see or know of flaws/pitfalls with this approach or know of a better way to accomplish this?
EDIT: Clarifying the reason behind this question.
When an error occurs when processing a record, this can leave UoW / EntityManger in a position where it can no longer persist without being cleared. In my particular case the error left an existing changed entity with a link non-persisted entity where the relations was not configured to cascade persist, which causes all subsequent persists to fail. At this point, if I want to keep processing the batch and skip the failing record, I have two choices:
1) Clear the EntityManager and reload all the business logic entities from the database. but this means that the recovery function can't be generic and has to be customize to know what entities to reload and adjusted each time that changes.
2) Clean the EntityManager using the existing capabilities of UnitOfWork, this allows the code to be generic and does not require ongoing modification.