Question

I'm trying to figure out if It's possible to query something like this (because I can't make it work)

$query = $em->createQuery("SELECT l FROM Bundle\EngMgmtBundle\Entity\Project p, 
                                      Bundle\EngMgmtBundle\Entity\Line l,
                                      Bundle\EngMgmtBundle\Entity\Site s 
                                      WHERE p.leader = :usr AND p.sites = s.id AND s.line = l.id");
            $query->setParameter('usr', $this->get('security.context')->getToken()->getUser());

I get:

[Semantical Error] line 0, col 289 near 'sites = s.id': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected. 

Meaning I can't query directly on project.sites like I am doing... How can I turn it around to make it work?

Info:

I have these Entities: Project, Line, Site and I need to query all the lines related to the projects (or project) where the logged user is responsable (leader). I've made this sort of queries before just not with a ManyToMany relationship in between.

a Project has many Sites and many Sites belong to many Projects, a Site has a line and a line has many sites.

This is the basic structure for each entity:

Project:

class Project
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\UserBundle\Entity\User")
      * @ORM\JoinColumn(name="leader_id", referencedColumnName="id",nullable=false)
      */
    private $leader;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\ClientBundle\Entity\Client")
      * @ORM\JoinColumn(name="client_id", referencedColumnName="id",nullable=false)
      */
    private $client;

     /**
     * @ORM\ManyToMany(targetEntity="Bundle\EngMgmtBundle\Entity\Site")
     * @ORM\JoinTable(name="Project_Sites",
     *      joinColumns={@ORM\JoinColumn(name="site_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="project_id", referencedColumnName="id")}
     *      )
     */
    private $sites;

        public function __construct()
    {
        $this->sites = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Project
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set leader
     *
     * @param string $leader
     * @return Project
     */
    public function setLeader(\Bundle\UserBundle\Entity\User $leader)
    {
        $this->leader = $leader;

        return $this;
    }

    /**
     * Get leader
     *
     * @return string 
     */
    public function getLeader()
    {
        return $this->leader;
    }

    /**
     * Set client
     *
     * @param string $client
     * @return Project
     */
    public function setClient(\Bundle\ClientBundle\Entity\Client $client)
    {
        $this->client = $client;

        return $this;
    }

    /**
     * Get client
     *
     * @return string 
     */
    public function getClient()
    {
        return $this->client;
    }

    /**
     * Get Sites
     *
     * @return array 
     */
    public function getSites()
    {
        return $this->sites;
    }

    /* Returns Project's Name */
    public function __toString() 
    {
        return $this->name;
    }
}

Site:

class Site
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\EngMgmtBundle\Entity\Line")
      * @ORM\JoinColumn(name="line_id", referencedColumnName="id",nullable=false)
      */
    private $line;

    /**
     * @var string
     *
     * @ORM\Column(name="latitude", type="string", length=255)
     */
    private $latitude;

    /**
     * @var string
     *
     * @ORM\Column(name="longitude", type="string", length=255)
     */
    private $longitude;

    /**
     * @var string
     *
     * @ORM\Column(name="internal_id", type="string", length=255, nullable=true)
     */
    private $internalId;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\EngMgmtBundle\Entity\Priority")
      * @ORM\JoinColumn(name="priority_id", referencedColumnName="id",nullable=false)
      */
    private $priority;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\EngMgmtBundle\Entity\Location")
      * @ORM\JoinColumn(name="location_id", referencedColumnName="id",nullable=false)
      */
    private $state;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set line
     *
     * @param string $line
     * @return Site
     */
    public function setLine(\Bundle\EngMgmtBundle\Entity\Line $line)
    {
        $this->line = $line;

        return $this;
    }

    /**
     * Get line
     *
     * @return string 
     */
    public function getLine()
    {
        return $this->line;
    }

    /**
     * Set latitude
     *
     * @param string $latitude
     * @return Site
     */
    public function setLatitude($latitude)
    {
        $this->latitude = $latitude;

        return $this;
    }

    /**
     * Get latitude
     *
     * @return string 
     */
    public function getLatitude()
    {
        return $this->latitude;
    }

    /**
     * Set longitude
     *
     * @param string $longitude
     * @return Site
     */
    public function setLongitude($longitude)
    {
        $this->longitude = $longitude;

        return $this;
    }

    /**
     * Get longitude
     *
     * @return string 
     */
    public function getLongitude()
    {
        return $this->longitude;
    }

    /**
     * Set internalId
     *
     * @param string $internalId
     * @return Site
     */
    public function setInternalId($internalId)
    {
        $this->internalId = $internalId;

        return $this;
    }

    /**
     * Get internalId
     *
     * @return string
     */
    public function getInternalId()
    {
        return $this->internalId;
    }
/**
     * Set name
     *
     * @param string $name
     * @return Site
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Set priority
     *
     * @param string $priority
     * @return Site
     */
    public function setPriority(\Bundle\EngMgmtBundle\Entity\Priority $priority)
    {
        $this->priority = $priority;

        return $this;
    }

    /**
     * Get priority
     *
     * @return string 
     */
    public function getPriority()
    {
        return $this->priority;
    }
        /**
     * Set state
     *
     * @param string $state
     * @return Site
     */
    public function setState(\Bundle\EngMgmtBundle\Entity\Location $state)
    {
        $this->state = $state;

        return $this;
    }

    /**
     * Get state
     *
     * @return string 
     */
    public function getState()
    {
        return $this->state;
    }
    /* Returns Site's Name */
    public function __toString() 
    {
        return $this->name;
    }

Line:

class Line
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
      * @ORM\OneToOne(targetEntity="Bundle\UserBundle\Entity\User")
      * @ORM\JoinColumn(name="supervisor_id", referencedColumnName="id",nullable=false)
      */
    private $supervisor;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Line
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set supervisor
     *
     * @param string $supervisor
     * @return Line
     */
    public function setSupervisor(\Bundle\UserBundle\Entity\User $supervisor)
    {
        $this->supervisor = $supervisor;

        return $this;
    }

    /**
     * Get supervisor
     *
     * @return string 
     */
    public function getSupervisor()
    {
        return $this->supervisor;
    }

     /* Returns Line's Name */
    public function __toString() 
    {
        return $this->name;
    }

I'd really appreciate any help you're able to offer me. Thanks in advance.

Was it helpful?

Solution

Where is your code for this? From the way you are getting the security context, I guess it might be in a controller? Maybe this query should go in a repository method for the Project entity? I guess using the Query Builder is the easiest way to do something like this. I haven't been able to test this so it probably won't work by just copy and pasting but hopefully it will be vaguely useful anyway...

    $em->createQueryBuilder('p')
        ->select('p', 's', 'l')
        ->leftJoin('p.sites', 's')
        ->leftJoin('s.line', 'l')
        ->where('p.leader = :user')
        ->setParameter('user', $user)
        ->getQuery()
        ->getResult();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top