Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine2 Caching of updated Elements

I have a problem with doctrine. I like the caching, but if i update an Entity and flush, shouldn't doctrine2 be able to clear it's cache? Otherwise the cache is of very little use to me since this project has a lot of interaction and i would literally always have to disable the cache for every query. The users wouldn't see their interaction if the cache would always show them the old, cached version.

Is there a way arround it?

like image 549
Andresch Serj Avatar asked May 15 '12 16:05

Andresch Serj


3 Answers

Are you talking about saving and fetching a new Entity within the same runtime (request)? If so then you need to refresh the entity.

$entity = new Entity();
$em->persist($entity);
$em->flush();
$em->refresh($entity);

If the entity is managed and you make changes, these will be applied to Entity object but only persisted to your database when calling $em->flush().

If your cache is returning an old dataset for a fresh request (despite it being updated successfully in the DB) then it sounds like you've discovered a bug. Which you can file here >> http://www.doctrine-project.org/jira/secure/Dashboard.jspa

like image 52
Lee Davis Avatar answered Nov 06 '22 10:11

Lee Davis


Doctrine2 never has those delete methods such as deleteByPrefix, which was in Doctrine1 at some point (3 years ago) and was removed because it caused more trouble.

The page http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#deleting is outdated (The next version of the doctrine2 document will see those methods removed). The only thing you can do now is manually managing the cache: find the id and delete it manually after each update.

More advanced doctrine caching is WIP: https://github.com/doctrine/doctrine2/pull/580.

like image 30
Chuan Ma Avatar answered Nov 06 '22 10:11

Chuan Ma


This is according to the documentation on Doctrine2 on how to clear the cache. I'm not even sure this is what you want, but I guess it is something to try.

Doctrine2's cache driver has different levels of deleting cached entries.

You can delete by the direct id, using a regex, by suffix, by prefix and plain deleting all values in the cache

So to delete all you'd do:

$deleted = $cacheDriver->deleteAll();

And to delete by prefix, you'd do:

$deleted = $cacheDriver->deleteByPrefix('users_');

I'm not sure how Doctrine2 names their cache ids though, so you'd have to dig for that.

Information on deleting cache is found here: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#deleting

To get the cache driver, you can do the following. It wasn't described in the docs, so I just traced through the code a little.

I'm assuming you have an entity manager instance in this example:

$config = $em->getConfiguration(); //Get an instance of the configuration
$queryCacheDriver = $config->getQueryCacheImpl(); //Gets Query Cache Driver
$metadataCacheDriver = $config->getMetadataCacheImpl(); //You probably don't need this one unless the schema changed

Alternatively, I guess you could save the cacheDriver instance in some kind of Registry class and retrieve it that way. But depends on your preference. Personally I try not to depend on Registries too much.

Another thing you can do is tell the query you're executing to not use the result cache. Again I don't think this is what you want, but just throwing it out there. Mainly it seems you might as well turn off the query cache altogether. That is unless it's only a few specific queries where you don't want to use the cache.

This example is from the docs: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#result-cache

$query = $em->createQuery('select u from \Entities\User u');
$query->useResultCache(false); //Don't use query cache on this query
$results = $query->getResult();
like image 25
Gohn67 Avatar answered Nov 06 '22 11:11

Gohn67