DDC-992: ManyToMany self referencing association bug with lazy loading #5527

Closed
doctrinebot opened this Issue Jan 19, 2011 · 5 comments

2 participants

@doctrinebot

Jira issue originally created by user vigor_bg:

Hi there I encountered a bug. When was trying to get ManyToMany self referencing association via lazy loading.

Here is my Entity.

use Doctrine\Common\Collections\ArrayCollection;

/****
 *
 * @Table(name="Roles")
 * @entity(repositoryClass="Users*Model*RoleRepo")
 */

class Users*Model_Entity_Role extends Viscomp_Doctrine_Entity*Abstract
{
/****
     *  @Id  @Column(name="roleID", type="integer")
     *  @GeneratedValue(strategy="AUTO")
     *
     */
    protected $roleID;

    /****
     * @Column (name="name", type="string", length="45")
     *
     *
     */
    protected $name;

    /****
     * @Column (name="shortName", type="string", length="45")
     *
     *
     */
    protected $shortName;

    /****
     * @ManyToMany (targetEntity="Users*Model_Entity*Role", mappedBy="extends")
     */
    protected $extendedBy;

    /****
     * @ManyToMany (targetEntity="Users*Model_Entity*Role", inversedBy="extendedBy")
     * @JoinTable (name="RoleRelations",
     *      joinColumns={@JoinColumn(name="roleID", referencedColumnName="roleID")},
     *      inverseJoinColumns={@JoinColumn(name="extendsRoleID", referencedColumnName="roleID")}
     *      )
     */
    protected $extends;

    public function **construct() {
        $this->extends = new ArrayCollection;
        $this->extendedBy = new ArrayCollection;
   }

}

When I call

$test = $this->getEntityManager()->getRepository('Users*Model_Entity*Role')->findOneBy(array('roleID' => 3));
Doctrine\Common\Util\Debug::dump($test); die;

The SQL that is generated is :


SELECT t0.roleID AS roleID1, t0.name AS name2, t0.shortName AS shortName3 FROM Roles t0 WHERE t0.roleID = ? array(1) { [0]=>  int(3) } 

SELECT t0.roleID AS roleID1, t0.name AS name2, t0.shortName AS shortName3 FROM Roles t0 INNER JOIN RoleRelations ON t0.roleID = RoleRelations.roleID WHERE RoleRelations.extendsRoleID = ?
array(1) {
  [0]=>
  int(3)
}
SELECT t0.roleID AS roleID1, t0.name AS name2, t0.shortName AS shortName3 FROM Roles t0 INNER JOIN RoleRelations ON t0.roleID = RoleRelations.extendsRoleID WHERE t0.roleID = ?
array(1) {
  [0]=>
  int(3)
}

In the last SQL query there is a mistake in the where clause it should be RoleRelations.roleID = ? and not t0.roleID = ?. And because of that it is not returning correct result.

@doctrinebot

Comment created by vigor_bg:

The solution that I found is in the class BasicEntityPersister on line 1123 we have

 $conditionSql .= $this->*getSQLTableAlias($this->*class->name) . '.';

and i replace it with

if ($assoc !== null
    && $assoc['targetEntity'] == $assoc['sourceEntity']
    && $assoc['type'] == ClassMetadata::MANY*TO*MANY) {
        $owningAssoc = $assoc['isOwningSide'] ? $assoc : $this->_em->getClassMetadata($assoc['targetEntity'])
                                                                   ->associationMappings[$assoc['mappedBy']];
    $conditionSql .= $this->*class->getQuotedJoinTableName($owningAssoc, $this->*platform) . '.';

} else {
         $conditionSql .= $this->*getSQLTableAlias($this->*class->name) . '.';
}

I am not sure if that is the correct answer but as far as i have tested it doesn't mess up with the normal many to many association via join table.

@doctrinebot

Comment created by @beberlei:

There is a simple workaround if you rename the "roleID" from the join table to something else, childRoleID for example. This should work for now. I am looking into a way to fix this issue.

@doctrinebot

Comment created by vigor_bg:

Ok thanks :)

@doctrinebot

Comment created by @beberlei:

Fixed, merged into 2.0.x branch.

@doctrinebot

Issue was closed with resolution "Fixed"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.0.4 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment