I am using Doctrine 2 to map an academic schedule. Here's a simplified look at the relationships:
- A class has events (one-to-many)
- An event has a type (many-to-one)
- An event has a location (many-to-one)
Using $em->find()
I can fetch the class only, with lazy-loaded relations. Or using DQL with joins, I can eager load the entire object graph. Is there a solution that's in-between?
I want to fetch a class with lazy-loaded relations, and then under certain conditions trigger an eager load of the event relationship and all the event properties. So when I call something like $class->getEventsHydrateAll()
, all of the events and event types and event locations will be hydrated at once.
I think I could accomplish this by updating my event schema to flag the type and location relationships as fetch="EAGER"
. But I'd like to have control over when this deep hydration occurs.
Here's one attempt I made in my class repository, but Doctrine is running individual queries to lookup each type and location.
$query = $this->_em->createQuery('
SELECT c FROM My\Entity\Class c
WHERE c.id = :classId
');
$query->setParameter('classId', $classId)
->setFetchMode('My\Entity\Event', 'type', 'EAGER')
->setFetchMode('My\Entity\Event', 'location', 'EAGER');
try {
return $query->getSingleResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return NULL;
}
Does anyone know if Doctrine supports this? Thanks!
Best Answer
I'm not sure if this will help you, but this is how I solved it.
First a bit of background for my situation. I'm currently creating an OAuth 2 implementation on which I want fine grain control over the scopes. Scopes are quite granular to star with for (e.g. email, username, etc), then you can set individual permissions on each of them each for read, create, edit and delete.
Here is a database diagram loosely showing that relationship:
So my issue was, how do I, for example, see if a particular token is allowed to read (permission) a username (scope)?
If I load the token, then get all of it's permissions, then foreach read permission, I check for the username scope, then that's a lot of database access.
Test code:
Query log:
However, we can see here that the bulk of this is collecting the scopes attached to the permissions. We can use the eager flag on the relationship from permission to scope to grab the scopes with the permissions:
Note the
fetch="EAGER"
flag on the ManyToOne annotation.Now if we run the exact same code: