I'm using Doctrine 2's result cache on a query retrieving the number of new messages of a user (messaging app):
$query->useResultCache(true, 500, 'messaging.nb_new_messages.'.$userId);
I tried to invalidate this cache like this (in my entity repository):
public function clearNbNewMessagesOfUserCache($userId) {
$cacheDriver = $this->getEntityManager()->getConfiguration()->getResultCacheImpl();
$result = $cacheDriver->delete('skepin_messaging.nbNewMessages.'.$userId);
if (!$result) {
return false;
}
return $cacheDriver->flushAll();
}
So that I don't need to make a useless query on each page of my website.
My questions: is that a recommended practice? Will I eventually run into problems?
I had the idea to build an onFlush hook. There you have all entities queued for inserts, updates and deletes hence you can invalidate the caches depending on entity name and identifier etc.
Unfortunately, I have not yet build any event listeners but I definitely plan to build such a thing for my project.
Here is a link to the doctrine documentation for the onFlush event
Edit: There is even an easier way to implement events. In an entity class you can add @HasLifecycleCallbacks to the annotations and than you can define a function with a @PreUpdate or @PrePersist annotation. Than every time this model is updated or persisted this function will be called.
/**
* @Entity
* @Table(name="SomeEntity")
* @HasLifecycleCallbacks
*/
class SomeEntity
{
...
/**
* @PreUpdate
* @PrePersist
*/
public function preUpdate()
{
// This function is called every time this model gets updated
// or a new instance of this model gets persisted
// Somethink like this maybe...
// I have not yet completely thought through all this.
$cache->save(get_class($this) . '#' . $this->getId(), $this);
}
}
So maybe this can be used to invalidate every single instance of an entity?
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