Doctrine SoftDelete

I ran into a problem with Doctrine’s SoftDelete extension a while back and managed to get some time today to finally track down what is happening.  I have a Symfony application with a number of related Doctrine entity classes. In most cases the parent entity uses cascade={"remove"} in the association annotation so Doctrine will remove the children automatically. With the SoftDelete extenation enabled, this rather elegantly results in the child entities getting their $deleted_at property set just like the parent. Very nice.

The trouble comes when I actually want to delete the parent entity. This came up in my unit tests where I was trying to clean up entities being persisted. I have a setUp() method in the unit test class that disables SoftDelete for the parent entity and looks for leftovers from previous tests then re-enabled SoftDelete. It then iterates through the object it found calling remove($obj) and flush() twice – once to soft-delete them then again to hard-delete them.

The double-remove logic worked fine until there were leftover child entities. It turns out the first time causes the delete timestamp properties for the parent and children to get set. When the second remove is called, it looks for children but doesn’t find them because they have their deleted field set and they’re hidden. The resulting transaction only includes the parent so the database throws a referential integrity constraint violation error because the child records still reference the parent. I’d need to disable SoftDelete for the children to make this work.

For now, I’ve just removed the SoftDelete extension from the application and will revisit it later.