My friends and family are under attack in Ukraine. Donate to protect them directly or help international organizations.

Forcing Doctrine to Persist

August 12th, 2015

I stumbled upon a case where Doctrine would refuse to persist my entity due to a very special circumstance. Here's the context: I'm using a generic method in my Repository to fetch a Post. I'm selecting partial fields like this:

SELECT PARTIAL post.{id, name} ...

If the entity is found, then I proceed to delete it by setting is_deleted to true, persisting and then flushing:

$post->is_deleted = true;
$this->getEntityManager()->persist($post);
$this->getEntityManager()->flush();

It doesn't save the entity. It skips it entirely. The column is mapped though. The problem is that the UnitOfWork checks the new data against the originally loaded data, then skips the fields that were not originally loaded. This seems to be the intended behavior. This in turn causes the whole entity to be skipped. I even tried selecting the column as HIDDEN (a DQL keyword), still no luck. In contrast, if I were to update the "name" property, it would have saved, because it was loaded in the SELECT.

Thankfully, the UnitOfWork has a public method that deals with it:

$this->getEntityManager()->getUnitOfWork()->setOriginalEntityProperty(spl_object_hash($post), 'is_deleted', false);

The hash refers to the specific instance, then you provide the mapped property name and the value. The value must be different from the one that you're setting later, otherwise it will also be skipped. Call this just before setting/persisting/flushing and you're in business.

Previous: Converting a Joined Resultset Into a Hierarchy Next: Creating Courses and Talks with Mind Maps