Skip to content
Advertisement

Loading Doctrine entities in postLoad

I have an entity which implements a postLoad lifecycle event method. This method conditionally updates the entity and attempts to save it. Something along the lines of:

/** 
 * @PostLoad 
 */
public function checkExpiryDate()
{
    $currentDate = new App_Date();

    // Check the expiry date here
    if ($currentDate->getTimestamp() > $this->getDateExpired()->getTimestamp()) {
        $this->Status = "expired";
        $this->ServiceLayer->saveEntity($this);
    }
}

However, I’m receiving the following error:

Call to a member function fetch() on a non-object in Doctrine/ORM/Internal/Hydration/ObjectHydrator.php on line 149

It seems I’m unable to save an entity during postLoad.

I stumbled across this ticket which suggests registering the ObjectHydrator under a new key and specifying the hydrator during any new queries.

However, I’m wondering if there is a nice way to implement this at a more abstract level; I would like to automatically register a new ObjectHydrator whenever a query is built during a postLoad dispatch.

Additionally could anyone briefly explain why this is an issue in the first place? From what I can see the query is being removed once the hydrator has been used, but I don’t see why this would be a problem when a new query is built, even if the hydrator is reused.

Thanks for any pointers!

Advertisement

Answer

This is unsupported, especially if you are calling EntityManager operations inside your service layer.

You would run into every possible weird race condition because you are basically re-using the same hydrators and destroying their internal state, rendering them useless while they are still hydrating your resultset.

This is a known issue, which has workarounds if you really need to handle this initialization logic during @PostLoad. See http://www.doctrine-project.org/jira/browse/DDC-1010

Instead of using a listener to populate missing dependencies of your object, consider using your service layer to handle that after you fetch the object from the entity manager. This anyway will disallow you from having any proxies for the entity in your example.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement