Usar JOIN en Symfony2 / Doctrine SQL

Tengo un problema al intentar usar QueryBuilder O DQL.

Tengo la siguiente relación:

Usuario Perfil RouteGroup Route

Me gustaría hacer un DQL que enumere todas las rutas a las que tiene acceso un usuario específico. Puedo obtener esta información con el siguiente código:

$usr = $this->container->get('security.context')->getToken()->getUser(); foreach ($usr->getProfiles() as $profile){ foreach ($profile->getRoutegroups() as $routegroup){ var_dump($routegroup->getRoutes()->toArray()); } } 

Por una razón obvia no puedo usar este código, de lo contrario sobrecargaré mi servidor, jajaja.

Intenté los siguientes enfoques:

DQL:

 $em->createQuery('SELECT p FROM CRMCoreBundle:User u JOIN CRMCoreBundle:Profile p JOIN CRMCoreBundle:RoleGroup rg JOIN CRMCoreBundle:Role r WHERE u.id=:user') ->setParameter('user', $user->getId()) ->getResult(); 

QueryBuilder (intenté usar u.profiles – el nombre de la relación en lugar de la entidad – pero esto tampoco funcionó):

 $em->createQueryBuilder() ->select('r') ->from('CRMCoreBundle:User', 'u') ->innerJoin('u.profiles','p') ->where('u.id = :user_id') ->setParameter('user_id', $user->getId()) ->getQuery() ->getResult(); 

¿¿¿Puede alguien ayudar, por favor???

ACTUALIZACIÓN: Probé la solución de Zeljko e hice este guión:

  return $this->getEntityManager() ->createQueryBuilder() ->select('u, r') ->from('CRMCoreBundle:User', 'u') ->innerJoin('u.profiles','p') ->innerJoin('p.routegroups','rg') ->innerJoin('rg.routes','r') ->where('u.id = :user_id')->setParameter('user_id', $user->getId()) ->getQuery() ->getResult(); 

Pero tengo este error:

 The parent object of entity result with alias 'r' was not found. The parent alias is 'rg'. 

Si cambio “-> seleccione (‘u, r’)” a “-> seleccione (‘r’)” obtengo esto:

 [Semantical Error] line 0, col -1 near 'SELECT r FROM': Error: Cannot select entity through identification variables without choosing at least one root entity alias. 

Después de probar algunas alternativas descubrí que podía hacer una búsqueda inversa, comenzando desde las rutas hasta los usuarios. La solución fue la siguiente:

 return $this->getEntityManager() ->createQueryBuilder() ->select('r') ->from('CRMCoreBundle:Route', 'r') ->innerJoin('r.routegroup','rg') ->innerJoin('rg.profiles','p') ->innerJoin('p.users','u') ->where('u.id = :user_id') ->setParameter('user_id', $user->getId()) ->getQuery() ->getResult(); 

En su DQL, está buscando usuarios, pero le preguntó cómo buscar rutas. ¿Qué es lo que realmente necesitas?

De todos modos, en RoutesRepository:

 $this->createQueryBuilder("r") ->innerJoin("r.Profiles", "p") ->innerJoin("p.User", "u") ->where("u=:user")->setParameter("user", $user) 

Puede que no entienda la relación, pero creo que puede cambiar esto para reflejar su código. Debes usar innerJoin, no leftJoin.

No soy un experto con Doctrine, pero acabo de resolver un problema muy similar. Resolví mi problema al incluir todas las entidades que estaba usando en las uniones en la parte SELECCIONAR de la statement.

No lo he probado, pero esto debería funcionar.

 $em->createQuery('SELECT u, p, rg, r FROM CRMCoreBundle:User u JOIN CRMCoreBundle:Profile p JOIN CRMCoreBundle:RoleGroup rg JOIN CRMCoreBundle:Role r WHERE u.id=:user') ->setParameter('user', $user->getId()) ->getResult(); 

No sé exactamente por qué, pero si no incluye las entidades, el responsable del tratamiento no conoce los alias que está utilizando para las entidades.

Espero que esto ayude.