DDC-2252: Trying to delete ManyToMany relatrionship with composite keys. #2833

Closed
opened 2026-01-22 14:05:16 +01:00 by admin · 13 comments
Owner

Originally created by @doctrinebot on GitHub (Jan 22, 2013).

Jira issue originally created by user yokoloko:

Hi,

When i try to delete some entities attached to an entity I've got the following message.

My entity is specified as follow.

    /****
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Entity\User\Account", inversedBy="memberships")
     * @ORM\JoinColumn(name="uid", referencedColumnName="uid")
     */
    protected $userAccount;

    /****
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Entity\Merchant\Account")
     * @ORM\JoinColumn(name="mch_accountid", referencedColumnName="accountid")
     */
    protected $merchantAccount;

    /****
     * @ORM\Column(type="datetime", name="date")
     * @var datetime
     */
    protected $date;

    /****
     * @ORM\Column(type="boolean")
     * @var boolean
     */
    protected $administrator;

    /****
     * @ORM\ManyToMany(targetEntity="Entity\User\Privilege", indexBy="privilegeid")
     * @ORM\JoinTable(name="fsbackend.user*mch_account*privilege",
     *   joinColumns={
     *       @ORM\JoinColumn(name="mch*accountid", referencedColumnName="mch*accountid"),
     *       @ORM\JoinColumn(name="uid", referencedColumnName="uid")
     *   },
     *   inverseJoinColumns={
     *       @ORM\JoinColumn(name="privilegeid", referencedColumnName="privilegeid")
     *   }
     * )
     */
    protected $privileges;

I delete the related entities

    $membership->getPrivileges()->clear();

    $this->_em->persist($userAccount);
    $this->_em->flush();

I tried on doctrine 2.1.7 and the last doctrine version and same thing happens.

Please find attached the error log.

Originally created by @doctrinebot on GitHub (Jan 22, 2013). Jira issue originally created by user yokoloko: Hi, When i try to delete some entities attached to an entity I've got the following message. My entity is specified as follow. ``` /**** * @ORM\Id * @ORM\ManyToOne(targetEntity="Entity\User\Account", inversedBy="memberships") * @ORM\JoinColumn(name="uid", referencedColumnName="uid") */ protected $userAccount; /**** * @ORM\Id * @ORM\ManyToOne(targetEntity="Entity\Merchant\Account") * @ORM\JoinColumn(name="mch_accountid", referencedColumnName="accountid") */ protected $merchantAccount; /**** * @ORM\Column(type="datetime", name="date") * @var datetime */ protected $date; /**** * @ORM\Column(type="boolean") * @var boolean */ protected $administrator; /**** * @ORM\ManyToMany(targetEntity="Entity\User\Privilege", indexBy="privilegeid") * @ORM\JoinTable(name="fsbackend.user*mch_account*privilege", * joinColumns={ * @ORM\JoinColumn(name="mch*accountid", referencedColumnName="mch*accountid"), * @ORM\JoinColumn(name="uid", referencedColumnName="uid") * }, * inverseJoinColumns={ * @ORM\JoinColumn(name="privilegeid", referencedColumnName="privilegeid") * } * ) */ protected $privileges; ``` I delete the related entities ``` $membership->getPrivileges()->clear(); $this->_em->persist($userAccount); $this->_em->flush(); ``` I tried on doctrine 2.1.7 and the last doctrine version and same thing happens. Please find attached the error log.
admin added the Bug label 2026-01-22 14:05:16 +01:00
admin closed this issue 2026-01-22 14:05:17 +01:00
Author
Owner

@doctrinebot commented on GitHub (Jan 22, 2013):

Comment created by @ocramius:

[~yokoloko] is the schema validated by the cli tools?

@doctrinebot commented on GitHub (Jan 22, 2013): Comment created by @ocramius: [~yokoloko] is the schema validated by the cli tools?
Author
Owner

@doctrinebot commented on GitHub (Jan 22, 2013):

Comment created by yokoloko:

Yes it's validated by the cli tools, if you are talking about the orm:validate-schema command.

@doctrinebot commented on GitHub (Jan 22, 2013): Comment created by yokoloko: Yes it's validated by the cli tools, if you are talking about the orm:validate-schema command.
Author
Owner

@doctrinebot commented on GitHub (Jan 23, 2013):

Comment created by yokoloko:

I think the problem is that my @Id are entities.

@doctrinebot commented on GitHub (Jan 23, 2013): Comment created by yokoloko: I think the problem is that my @Id are entities.
Author
Owner

@doctrinebot commented on GitHub (Jan 23, 2013):

Comment created by @ocramius:

[~yokoloko] can you abstract it away into a test?

@doctrinebot commented on GitHub (Jan 23, 2013): Comment created by @ocramius: [~yokoloko] can you abstract it away into a test?
Author
Owner

@doctrinebot commented on GitHub (Jan 23, 2013):

Comment created by yokoloko:

Here is my test case.

I put it IN Doctrine\Test\ORMJT.
I don't really know if you need something else, please let met know.

<?php

namespace Doctrine\Tests\ORMJT;

use Doctrine\ORM\Query;
use Doctrine\Common\Collections\ArrayCollection;

require*once __DIR_* . '/../TestInit.php';

/****
 * Functional tests for the Single Table Inheritance mapping strategy.
 *
 * @author robo
 */
class AdvancedAssociationTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
    protected function setUp() {
        parent::setUp();
        try {
            $this->_schemaTool->createSchema(array(
                $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\User'),
                $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\MerchantAccount'),
                $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\Membership'),
                $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\Privilege')
            ));
        } catch (\Exception $e) {
            // Swallow all exceptions. We do not test the schema tool here.
        }
    }

    public function testIssue()
    {
        $user = new User;
        $merchantAccount = new MerchantAccount;
        $privilege = new Privilege;
        $membership = new Membership($user, $merchantAccount);
        $membership->addPrivilege($privilege);

        $this->_em->persist($user);
        $this->_em->persist($merchantAccount);
        $this->_em->persist($privilege);
        $this->_em->flush();

        $this->_em->persist($membership);
        $this->_em->flush();

        $membership->getPrivileges()->clear();

        $this->_em->flush();

        // Never reached
        $this->assertTrue(true);
    }
}


/****
 * @Entity
 * @Table(name="mch_account")
 */
class MerchantAccount
{
    /****
     * @Id @GeneratedValue
     * @Column(type="bigint")
     * @var bigint $accountid
     */
    protected $accountid;
}

/****
 * @Entity(repositoryClass="Repository\User\PrivilegeRepository")
 * @Table(name="acl_privilege")
 */
class Privilege
{
    /****
     * @Id @GeneratedValue
     * @Column(type="bigint")
     * @var integer
     */
    protected $privilegeid;
}

/****
 * @Entity
 * @Table(name="user_account")
 */
class User {
    /****
     * @Id @GeneratedValue
     * @Column(type="bigint")
     * @var integer
     */
    protected $uid;

    /****
     * @OneToMany(targetEntity="Membership", mappedBy="userAccount", cascade={"persist"})
     * @JoinColumn(name="uid", referencedColumnName="uid")
     */
    protected $memberships;

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

    public function getMemberships()
    {
        return $this->memberships;
    }

    public function addMembership(Membership $membership)
    {
        $this->memberships[] = $membership;
    }
}

/****
 * @Entity
 * @Table(name="mch*account*member")
 * @HasLifecycleCallbacks
 */
class Membership
{
    /****
     * @Id
     * @ManyToOne(targetEntity="User", inversedBy="memberships")
     * @JoinColumn(name="uid", referencedColumnName="uid")
     */
    protected $userAccount;

    /****
     * @Id
     * @ManyToOne(targetEntity="MerchantAccount")
     * @JoinColumn(name="mch_accountid", referencedColumnName="accountid")
     */
    protected $merchantAccount;

    /****
     * @ManyToMany(targetEntity="Privilege", indexBy="privilegeid")
     * @JoinTable(name="user*mch_account*privilege",
     *   joinColumns={
     *       @JoinColumn(name="mch*accountid", referencedColumnName="mch*accountid"),
     *       @JoinColumn(name="uid", referencedColumnName="uid")
     *   },
     *   inverseJoinColumns={
     *       @JoinColumn(name="privilegeid", referencedColumnName="privilegeid")
     *   }
     * )
     */
    protected $privileges;

    public function **construct(User $user, MerchantAccount $merchantAccount)
    {
        $this->userAccount = $user;
        $this->merchantAccount = $merchantAccount;
        $this->privileges = new ArrayCollection();
    }

    public function addPrivilege($privilege)
    {
        $this->privileges[] = $privilege;
    }

    public function getPrivileges()
    {
        return $this->privileges;
    }
}

And i've got the following error

1) Doctrine\Tests\ORMJT\AdvancedAssociationTest::testIssue
Exception: [PHPUnit*Framework_Error_Notice] Undefined index: mch*accountid
@doctrinebot commented on GitHub (Jan 23, 2013): Comment created by yokoloko: Here is my test case. I put it IN Doctrine\Test\ORMJT. I don't really know if you need something else, please let met know. ``` <?php namespace Doctrine\Tests\ORMJT; use Doctrine\ORM\Query; use Doctrine\Common\Collections\ArrayCollection; require*once __DIR_* . '/../TestInit.php'; /**** * Functional tests for the Single Table Inheritance mapping strategy. * * @author robo */ class AdvancedAssociationTest extends \Doctrine\Tests\OrmFunctionalTestCase { protected function setUp() { parent::setUp(); try { $this->_schemaTool->createSchema(array( $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\User'), $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\MerchantAccount'), $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\Membership'), $this->_em->getClassMetadata('Doctrine\Tests\ORMJT\Privilege') )); } catch (\Exception $e) { // Swallow all exceptions. We do not test the schema tool here. } } public function testIssue() { $user = new User; $merchantAccount = new MerchantAccount; $privilege = new Privilege; $membership = new Membership($user, $merchantAccount); $membership->addPrivilege($privilege); $this->_em->persist($user); $this->_em->persist($merchantAccount); $this->_em->persist($privilege); $this->_em->flush(); $this->_em->persist($membership); $this->_em->flush(); $membership->getPrivileges()->clear(); $this->_em->flush(); // Never reached $this->assertTrue(true); } } /**** * @Entity * @Table(name="mch_account") */ class MerchantAccount { /**** * @Id @GeneratedValue * @Column(type="bigint") * @var bigint $accountid */ protected $accountid; } /**** * @Entity(repositoryClass="Repository\User\PrivilegeRepository") * @Table(name="acl_privilege") */ class Privilege { /**** * @Id @GeneratedValue * @Column(type="bigint") * @var integer */ protected $privilegeid; } /**** * @Entity * @Table(name="user_account") */ class User { /**** * @Id @GeneratedValue * @Column(type="bigint") * @var integer */ protected $uid; /**** * @OneToMany(targetEntity="Membership", mappedBy="userAccount", cascade={"persist"}) * @JoinColumn(name="uid", referencedColumnName="uid") */ protected $memberships; public function **construct() { $this->memberships = new ArrayCollection; } public function getMemberships() { return $this->memberships; } public function addMembership(Membership $membership) { $this->memberships[] = $membership; } } /**** * @Entity * @Table(name="mch*account*member") * @HasLifecycleCallbacks */ class Membership { /**** * @Id * @ManyToOne(targetEntity="User", inversedBy="memberships") * @JoinColumn(name="uid", referencedColumnName="uid") */ protected $userAccount; /**** * @Id * @ManyToOne(targetEntity="MerchantAccount") * @JoinColumn(name="mch_accountid", referencedColumnName="accountid") */ protected $merchantAccount; /**** * @ManyToMany(targetEntity="Privilege", indexBy="privilegeid") * @JoinTable(name="user*mch_account*privilege", * joinColumns={ * @JoinColumn(name="mch*accountid", referencedColumnName="mch*accountid"), * @JoinColumn(name="uid", referencedColumnName="uid") * }, * inverseJoinColumns={ * @JoinColumn(name="privilegeid", referencedColumnName="privilegeid") * } * ) */ protected $privileges; public function **construct(User $user, MerchantAccount $merchantAccount) { $this->userAccount = $user; $this->merchantAccount = $merchantAccount; $this->privileges = new ArrayCollection(); } public function addPrivilege($privilege) { $this->privileges[] = $privilege; } public function getPrivileges() { return $this->privileges; } } ``` And i've got the following error ``` 1) Doctrine\Tests\ORMJT\AdvancedAssociationTest::testIssue Exception: [PHPUnit*Framework_Error_Notice] Undefined index: mch*accountid ```
Author
Owner

@doctrinebot commented on GitHub (Jan 23, 2013):

Comment created by @ocramius:

Thank you so far, this makes it much easier to work with it!

@doctrinebot commented on GitHub (Jan 23, 2013): Comment created by @ocramius: Thank you so far, this makes it much easier to work with it!
Author
Owner

@doctrinebot commented on GitHub (Jan 26, 2013):

Comment created by yokoloko:

Interesting fact, if I only have one column in my jointable it works fine.

eg.

class Membership
     *   ....
     *   @JoinTable(name="user*mch_account*privilege",
     *       joinColumns={
     *           @JoinColumn(name="uid", referencedColumnName="uid")
     *       }
     *   ....
@doctrinebot commented on GitHub (Jan 26, 2013): Comment created by yokoloko: Interesting fact, if I only have one column in my jointable it works fine. eg. ``` class Membership * .... * @JoinTable(name="user*mch_account*privilege", * joinColumns={ * @JoinColumn(name="uid", referencedColumnName="uid") * } * .... ```
Author
Owner

@doctrinebot commented on GitHub (Feb 7, 2013):

Comment created by yokoloko:

Ok here is my two cents solution. passes the tests.

@doctrinebot commented on GitHub (Feb 7, 2013): Comment created by yokoloko: Ok here is my two cents solution. passes the tests.
Author
Owner

@doctrinebot commented on GitHub (Mar 5, 2013):

Comment created by yokoloko:

Hi, any update on this issue?

@doctrinebot commented on GitHub (Mar 5, 2013): Comment created by yokoloko: Hi, any update on this issue?
Author
Owner

@doctrinebot commented on GitHub (Mar 5, 2013):

Comment created by @ocramius:

[~yokoloko] will be checking this tomorrow

@doctrinebot commented on GitHub (Mar 5, 2013): Comment created by @ocramius: [~yokoloko] will be checking this tomorrow
Author
Owner

@doctrinebot commented on GitHub (Mar 14, 2013):

Comment created by yokoloko:

Everything ok with the check?

@doctrinebot commented on GitHub (Mar 14, 2013): Comment created by yokoloko: Everything ok with the check?
Author
Owner

@doctrinebot commented on GitHub (Apr 16, 2013):

Comment created by @FabioBatSilva:

Fixed by : cef20890dc

@doctrinebot commented on GitHub (Apr 16, 2013): Comment created by @FabioBatSilva: Fixed by : https://github.com/doctrine/doctrine2/commit/cef20890dc75c11880827226e25f3fc6d5d66127
Author
Owner

@doctrinebot commented on GitHub (Apr 16, 2013):

Issue was closed with resolution "Fixed"

@doctrinebot commented on GitHub (Apr 16, 2013): Issue was closed with resolution "Fixed"
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#2833