Reputation: 58
I'm building a ZF2+Doctrine2 web application and I have implemented caching in my Entity Repositories.
public function findActive()
{
$query = $this->_em->createQueryBuilder();
$query->select('r')
->from('Admin\Entity\Brands', 'r')
->where('r.deleted = false')
->orderBy('r.name', 'ASC');
return $query->getQuery()
->useResultCache(true, 7200, 'brands_find_active')
->getResult();;
}
I have not been able to figure out how to inject caching logic for lookup queries.
Like if I have a users table with a role_id that links to the roles table and I perform a getRole()->getRoleName()
call. That causes an additional sql query to the role table. How do I cache the entire query/recursively?
Upvotes: 0
Views: 992
Reputation: 13558
Simply, you cannot. Doctrine performs "magic" queries for lazy loading. For instance, if you load your user, then roles are not automatically queries. Only if you call $user->getRole()
the role is queried.
This behaviour requires a so-called proxy pattern. A user in your code is not the Admin\Entity\User
object, but a Doctrine class which extends from your user. The proxy also holds an instance of the entity manager, so it can query for a role when you call getRole()
. Because if this proxy, it is very hard to serialize and deserialize the php objects.
Because of this pattern, you never can cache Doctrine entities really well. You also keep having trouble with the proxies and relations. The only way you can load them is not loading related entities and ensure the loading technique for __wakeup()
.
It's far more easier if you just use the Doctrine caches. You can configure the Doctrine caches with the ZF2 DoctrineModule with this piece of code in your config:
'doctrine' => array(
'configuration' => array(
'orm_default' => array(
'metadata_cache' => 'apc',
'query_cache' => 'apc',
'result_cache' => 'apc',
),
),
),
If you need to provide a namespace for the apc cache (e.g. you have multiple sites on one server) set the namespace via this config:
'doctrine' => array(
'cache' => array(
'apc' => array(
'namespace' => 'my-namespace',
),
),
),
Upvotes: 2