简体   繁体   中英

Symfony2: Left Join producing wrong query

I'm trying to build a query with doctrine query builder like this:

$q = $this
        ->createQueryBuilder('u')
        ->select('u, r')
        ->leftJoin('u.roles', 'r')
        ->where('u.username = :username OR u.email = :email')
        ->setParameter('username', $username)
        ->setParameter('email', $username)
        ->getQuery();`

This code produces 2 queries:

Query 1 is correct

SELECT t0.user_id AS user_id1, t0.username AS username2, t0.salt AS salt3, t0.password AS password4, t0.email AS email5, t0.is_active AS is_active6, t0.created AS created7, t0.updated AS updated8, t0.last_login AS last_login9 
FROM users t0 
WHERE t0.username = ? 
LIMIT 1 

Query 2 is not correct:

SELECT t0.role_id AS role_id1, t0.role AS role2 
FROM roles t0 
INNER JOIN user_role ON t0.id = user_role.role_id 
WHERE user_role.user_fk = ?

Query 2 should be:

SELECT t0.role_id AS role_id1, t0.role AS role2 
FROM roles t0 
INNER JOIN user_role ON t0.role_id = user_role.role_fk 
WHERE user_role.user_fk = ?

Entity\\Role looks like this:

/**
 * @ORM\Table(name="roles")
 * @ORM\Entity(repositoryClass="XXX\XXXBundle\Entity\Repository\RoleRepository")
 */
class Role implements RoleInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="role_id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $_roleId;
    /**
     * @ORM\Column(name="role", type="string", length=20, unique=true)
     */
    protected $_role;
    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
     * @ORM\JoinTable(name="user_role",
     *     joinColumns={@ORM\JoinColumn(name="role_fk", referencedColumnName="role_id")})
     */
    private $_users;
...

Entity\\User looks like this:

class User implements UserInterface, \Serializable  
    {
        /**
         * @ORM\Column(name="user_id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $_userId;
        ...
        /**
         * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
         * @ORM\JoinTable(name="user_role",
         *     joinColumns={@ORM\JoinColumn(name="user_fk", referencedColumnName="user_id")})
         */
        protected $_roles;
    ...

The annotation in the Entity\\Role code states the column names to use and the SELECT portion of the statement is using the correct names. The WHERE portion of the statement is using the correct column user_role.user_fk, this is defined in the Entity\\User code.

How do I stop doctrine using column names that do not exist and use the defined column names for the INNER JOIN part of the statement?

I found a solution which works.

Entity\\User needs to be altered to include the inverseJoinColumns on the annotation like this:

/**
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="_users")
 * @ORM\JoinTable(name="user_role",
 *     joinColumns={@ORM\JoinColumn(name="user_fk", referencedColumnName="user_id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="role_fk", referencedColumnName="role_id")})
 */
protected $_roles;

Entity\\Role needs to be altered to include the inverseJoinColumns like this:

/**
 * @ORM\ManyToMany(targetEntity="User", mappedBy="_roles")
 * @ORM\JoinTable(name="user_role",
 *     joinColumns={@ORM\JoinColumn(name="role_fk", referencedColumnName="role_id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="user_fk", referencedColumnName="user_id")})
 */
private $_users;

and the createQueryBuilder code needs to look like this:

$q = $this
        ->createQueryBuilder('u')
        ->select('u, r')
        ->from('XXXXXXBundle:User', 'u')
        ->leftJoin('u.roles', 'r', \Doctrine\ORM\Query\Expr\Join::ON, 'user_role.role_kf = r.role_id')
        ->where('u.username = :username OR u.email = :email')
        ->setParameter('username', $username)
        ->setParameter('email', $username)
        ->getQuery();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM