I have a repository where I'm trying to set up result caching. I've only been able to find a single example online for how to do this... but when I implement the example in one of my repositories I get an error. I am using APC for my caching and have enabled query caching to use APC in my config.yml file. I've allocated 512M to APC and its only using 50M currently (23M of this is for this single failed cache entry)
Here's the repository code I have:
class AchievementRepository extends EntityRepository
{
function findAchievementsByCategory($categoryObj)
{
$em=$this->getEntityManager()->createQuery("SELECT a FROM FTWGuildBundle:Achievement a where a.category=:category order by a.title")
->setParameter('category',$categoryObj);
$em->useResultCache(true,3600,'findAchievementsByCategory');
$result=$em->getResult();
return $result;
}
}
And when this is executed I get the following error
Notice: apc_store() [<a href='function.apc-store'>function.apc-store</a>]: "type" returned as member variable from __sleep() but does not exist in /data/www/ftw2/Symfony/vendor/doctrine-common/lib/Doctrine/Common/Cache/ApcCache.php line 80
When I look in my apc.php file to see what is cached, I find my cache entry in the user cache section with a stored value of
Fatal error: Nesting level too deep - recursive dependency? in /data/www/localhost/apc.php on line 1000
Can anyone provide me with some direction as to where I have gone wrong?
There are a couple columns in this entity which are ManyToOne, do I need to disable lazy load on this query for this to work? If so... how? EDIT: I enabled eager load by adding ,fetch="EAGER" to my ManyToOne mapping... no apples :(
EDIT #2: ANSWERED - Working class code (note, all properties of the entity class (Achievement) have been changed to protected)
class AchievementRepository extends EntityRepository
{
function findAchievementsByCategory($categoryObj)
{
$em=$this->getEntityManager()->createQuery("SELECT a FROM FTWGuildBundle:Achievement a where a.category=:category order by a.title")
->setParameter('category',$categoryObj);
$em->useResultCache(true,3600,'findAchievementsByCategory');
$result=$em->getArrayResult();
return $result;
}
}
When Doctrine caches an entity, it saves the serialized state of it. The problem is, private properties (the default visibility when generated by Doctrine) cannot be serialized. To fix this, you have to make your entity properties protected. More info: http://doctrine-orm.readthedocs.org/en/2.0.x/reference/working-with-objects.html#merging-entities
The other thing is a know issue that is (finally) fixed in Doctrine version 2.2, which will be in Symfony 2.1. If you can't upgrade for some reason, the only way to cache associations is to use getArrayResult
instead of populating entities.
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