Reputation: 1227
I'm trying to clean a collection of entities (that is, a table, in the relational jargon), those entities are instances of Color
, and I want to run a script that uses Doctrine 2 to delete all unreferenced Color
's. The problem is that Color
is referenced by many other entities in the system. So, I could think of two choices:
Color
on other entities on my system, and, if there is no reference, delete it.Obviously, the second choice is more simple than the first one, so I've tried that. The problem I had is that, when an entity removing fails, EM throw an exception, but also close the Entity Manager and I cannot use it anymore to delete the remaining colors!
I check commit
method for UnitOfWork
class at Doctrine 2 and in fact...
try {
... //Execute queries
$conn->commit();
} catch (Exception $e) {
$this->em->close();
$conn->rollback();
throw $e;
}
Is there any way to accomplish what I'm trying to do (maybe reopening Entity Manager)?
Do you believe that there is any better way?
Why Doctrine has this behaviour?
Also please note that I'm using Doctrine 2 with Symfony 2
Upvotes: 1
Views: 1941
Reputation: 20191
Ideally, you would define orphanRemoval
in your relations so you wouldn't need to bother with the removal. Other than that I can think of 3 solutions right now..
First, do you use CASCADE
in ON DELETE
when referencing colors
table?
If you do use CASCADE
I would suggest implementing Doctrine's batch processing as described here: BULK DELETE but here your $batchSize
would be exactly 1.
I, somehow, see the above solution as not-so-efficient and you could also achieve this by:
Color
entity and collect id
of Color
into the array.DELETE FROM AcmeDemoBundle:Color c WHERE c.id IN (:ids)
and set ids
parameter as usual.There is another solution if you do not use CASCADE
. You could execute raw sql:
DELETE IGNORE FROM color;
Here, referenced colors would not be deleted and would fire an error but due to IGNORE
it would end up only as warning.
Hope some of this helps....
Upvotes: 1
Reputation: 5158
Something like this:
// somewhere in ColorRepository.php
$this->createQueryBuilder("o")
->leftJoin("o.Relation1", "r1")
->leftJoin("o.Relation2", "r2)
->where("r1 IS NULL AND r2 IS NULL")
->delete() ;
This should load your entities (Color) only if they don't have relations with r1 and r2 anymore and delete them.
Upvotes: 0