Ask your Symfony questions! Pay money and get answers fast! (more info)

Symfony2 + Doctrine2 Memcache Issue Symfony

  • SOLVED

Hi all,

I've come across a problem that got me baffled when I use Memcache with Doctrine. Here's my setup (crucial parts):

config.yml:
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8

orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
metadata_cache_driver: apc
query_cache_driver: apc
result_cache_driver:
type: memcache
host: localhost
port: 11211
class: Doctrine\Common\Cache\MemcacheCache
instance_class: Memcache



In my showAction() method in UrlsController.php:

/**
* Finds and displays a Urls entity.
*
* @Route("/{id}/show", name="shorten_show")
* @Template()
*/
public function showAction($id)
{
$cache = new \Doctrine\Common\Cache\MemcacheCache;
$click_cache_id = md5('url_clicks_id='.$id);

$em = $this->getDoctrine()->getEntityManager();
$urls = $em->getRepository('UrlShortenerBundle:Urls')->find($id);

if (!$urls) {
throw $this->createNotFoundException('Unable to find Urls urls.');
}

$deleteForm = $this->createDeleteForm($id);

$query = $em->createQuery( 'select * from UrlShortener\Entity\Clicks where url_id ='.$id );
$query->setResultCacheDriver(new \Doctrine\Common\Cache\MemcacheCache());
$query->useResultCache(true, 3600, $click_cache_id);
$clicks = $query->getResult();

//if( $cache->contains($click_cache_id)) {
// $click = $cache->fetch($click_cache_id);
//} else {
// $clicks = $em->getRepository('UrlShortenerBundle:Clicks')->findBy( array('url_id' => $id ));
// $cache->save($click_cache_id, $clicks, 3600);
//}

return array(
'urls' => $urls,
'clicks' => $clicks,
'delete_form' => $deleteForm->createView(),
'base_href' => BASE_HREF
);
}



Running the above gives me an error:

Fatal error: Call to a member function get() on a non-object in /var/www/sc.pn/vendor/doctrine-common/lib/Doctrine/Common/Cache/MemcacheCache.php on line 100


I've tried another way as you can see in the commented out code in the above but to no avail. Still the same error.

Doing a little more digging, I put in debug trace in the doctrine MemcacheCache class as such:

class MemcacheCache extends AbstractCache
{
/**
* @var Memcache
*/
private $_memcache;

/**
* Sets the memcache instance to use.
*
* @param Memcache $memcache
*/
public function setMemcache(Memcache $memcache)
{
$this->_memcache = $memcache;
print_r($this->_memcache);
}

...

protected function _doFetch($id)
{

print_r($this->_memcache);
return $this->_memcache->get($id);
}

...


Running the controller again, I get the output in setMemcache():

Memcache Object
(
[connection] => Resource id #36
)


Above shows that the memcache instance is available and is set in the private _memcache.

BUT when it reaches the _doFetch() method, the <strong>print_r($this->_memcache) returned nothing</strong>.... ?!

It is as if the memcache instance was not set or disappeared. Can anyone please assist in this? Any help is deeply appreciated!

Answers (1)

2011-09-08

Florian Klein answers:

Hello,

You are not forced to call the setResultCacheDriver during the query building.

Try to comment this line:


$query->setResultCacheDriver(new \Doctrine\Common\Cache\MemcacheCache());


It will then use the cache driver you defined in the doctrine.orm part of your config.yml.


If you still want to use your own cache driver for this query, then you will have to instanciate correctly the Doctrine\Common\Cache\MemCacheCache class like that:




$cache = new Doctrine\Common\Cache\MemCacheCache;
$memcache = new Memcache;
$memcache->connect('localhost', 11211);

$cache->setMemcache($memcache);

$query->setResultCacheDriver($cache);




Cheers,
Florian.


Wicked comments:

I'll give that a go. What about using cache with such a line:

$clicks = $em->getRepository('UrlShortenerBundle:Clicks')->findBy( array('url_id' => $id ));


Thanks.


Florian Klein comments:

Doctrine2 doesn't use query cache neither result cache for this kind of calls, IMHO.




Wicked comments:

Thanks for that. Forever grateful!