0
votes

I'm trying to make a join in my repository class (Symfony 3 with Doctrine).

This is how it looks like:

public function findByRole($roles){
        $qb = $this->createQueryBuilder('u')
            ->join('user_role', 'ur', Join::ON, 'ur.id = u.customerId');
        $q = $qb->getQuery();

        $users = $q->getArrayResult();
        dump($users);
    }

And I've got this error:

[Semantical Error] line 0, col 49 near 'user_role ur': Error: Class 'user_role' is not defined.

There are two entity classes defined - User and Role. And Role is a property of User (ManyToMany).

There is also a joining table - user_role - do I need to create a class for every joining table even if I don't need it for my own purposes?

p.s. I know this error can be already found on Stackoverflow, but people having this issue probably have different problems.

Update:

Here's the User entity class (shortened):

/**
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User implements AdvancedUserInterface, \Serializable {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    //irrelevant code removed

    /**
     *
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Role", cascade = {"persist"}, inversedBy="users")
    *  @ORM\JoinTable(name="user_role",
    *      joinColumns={@ORM\JoinColumn(name="user_id",
    * referencedColumnName="id")},
    *      inverseJoinColumns={@ORM\JoinColumn(name="role_id",
    * referencedColumnName="id")}
    *      )
     */
    private $roles;

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


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

    ////////////////////////////////
    //roles

    /**
     * Add role
     * @param \AppBundle\Entity\Role $role
     *
     * @return User
     */
    public function addRole(\AppBundle\Entity\Role $role) {
        $this->roles[] = $role;
        return $this;
    }

    public function setRoles(\AppBundle\Entity\Role $role){
        $this->addRole($role);
        return $this;
    }
    /**
     * Remove role
     * @param \AppBundle\Entity\Role $role
     */
    public function removeRole(\AppBundle\Entity\Role $role) {
        $this->roles->removeElement($role);
    }

    /**
     * I know it probably should return simply $this->roles, but the interface I'm implementing requires an array of strings... But everything works fine, except joining user+roles  
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getRoles() {
        return $this->roles->toArray();
    }

    /**
     * Get roles
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getRoleEntities() {
        return $this->roles;
    }



}
1
It should be u.user_role. - qooplmao
@qooplmao thanks, but now I have this: [Semantical Error] line 0, col 61 near 'ur ON ur.id =': Error: Class AppBundle\Entity\User has no association named user_role what actually this 'u' means? I thought that it means user table, and there is no 'user_role' field, the 'user_role' is a completely different table (which joins users and roles) - konrad_firm
I assumed user_role was the property with relationship between user and roles. If there is no relationship then you will need one. Also probably have different problems kind of gives off the impression that you couldn't be bothered to look through the other answers. - qooplmao
No, it only means I did try to understand what their questions, and then looked at the anwers, but I know too little about Symfony, I've just noticed that I probably have problems with my mapping (annotations), and the answers did not mention it. - konrad_firm
Fair enough, just saying that's how it looks. From your update it looks like you would just need to use ->join('u.roles', 'ur'); - qooplmao

1 Answers

1
votes

I doctrine, all joined objects must be entities.

But you can map a many-to-many relationship between the entities User and Role, using user_role as a linkage table

In user table you might have a property $roles

/**
* @ManyToMany(targetEntity="Role", inversedBy="users")
* @JoinTable(name="user_role",
*      joinColumns={@JoinColumn(name="user_id",
* referencedColumnName="id")},
*      inverseJoinColumns={@JoinColumn(name="role_id",
* referencedColumnName="id")}
*      )
*/
private $roles;

and a property $users in role table

    /**
* @ManyToMany(targetEntity="User", inversedBy="roles")
* @JoinTable(name="user_role",
*      joinColumns={@JoinColumn(name="role_id",
* referencedColumnName="id")},
*      inverseJoinColumns={@JoinColumn(name="user_id",
* referencedColumnName="id")}
*      )
*/
private $users;

I've not tested this code. Surely It gonna need some tweeking. You also need to created the getters and setters for these properties.