I currently have an entity which I would like to modify slightly upon load. This modification will be a one time change which will then be persisted in a new field along with the entity.
To clarify my current objective: The entity is a "Location" and forms part of a nested set. It has a name, lft/rgt values and an Id. One computationally expensive task I was performing with this entity was to fetch a full location path and display it as text. For example, with the location entity "Waterloo" I want to display as "Waterloo|London|United Kingdom". This involves traversing through the entire set (to the root node).
To reduce the cost of this I've created a new field on the Location entity that can be stamped with this value (and updated as/when the location (or any location within the tree) name is modified). Considering my application is in a live state I need to avoid running this as a one off process as it would incur quite an intensive one-time hit on the DB, instead I'd like to apply this update as and when each location (without that value) is loaded. I assumed Doctrine's postLoad event mechanism would be perfect for achieving this, however..
The Location entities are not loaded directly by my application, they will always be the inverse side of a relation. With this is mind, and the fact that doctrine's postLoad event:
I have no way of gently making these modifications.
Anyone have any advice, or experience on this?
I was able to load the associated Location objects within the postLoad event by using the initializeObject() method on the Entity Manager.
/**
* Upon loading the object, if the location text isn't set, set it
* @param \Doctrine\ORM\Event\LifecycleEventArgs $args
*/
public function postLoad(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$this->em = $args->getEntityManager();
$entity = $args->getEntity();
if ($entity instanceof \Entities\Location)
{
if (is_null($entity->getPathText()))
{
$entity->setPathText("new value");
$this->em->flush($entity);
}
} elseif ($entity instanceof {parent Entity})
{
$location = $entity->getLocation();
// This triggers the postLoad event again, but this time with Location as the parent Entity
$this->em->initializeObject($location);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With