Skip to content

DDC-978: Many-To-Many relations are removed after Flush() #5512

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

2 participants

@doctrinebot

Jira issue originally created by user slasher:

Let's say we have three entities: User, Channel, and Log

Every time a User is created or updated, Channels are assigned to a Many-To-Many collection.
This action gets logged in the Log entity.

I have reproduced the bug in the Doctrine sandbox (see attachment). It's a fully working example.
This is a summary:

// Fetch two channels in an array
$channels = .......

// create a new user and assign channels
$user = new User();
$user->setName('FooBar');
$user->setChannels($channels);

//save the user
$em->persist($user);
$em->flush();

// log it
$log = new Log();
$log->setMessage('User created with two channels');
$log->setItem($user);

$em->persist($log);
$em->flush();
// Fetch two channels in an array
$channels = .......

// fetch an existing user, **change something to the user**, and assign channels
$user = .............
$user->setName('Gaz');
$user->setChannels($channels);

//save the user
$em->persist($user);
$em->flush();

// log it
$log = new Log();
$log->setMessage('User created with two channels');
$log->setItem($user);

$em->persist($log);
$em->flush();
// Fetch two channels in an array
$channels = .......

// fetch an existing user and only assign channels, change nothing else
$user = .............
$user->setChannels($channels);

//save the user
$em->persist($user);
$em->flush();

// log it
$log = new Log();
$log->setMessage('User created with two channels');
$log->setItem($user);

$em->persist($log);
$em->flush();

This last piece of code generates following SQL code (summarized):

DELETE FROM user_channels WHERE userId = 1
INSERT INTO user_channels (userId, channelId) VALUES (1, 2);
DELETE FROM user_channels WHERE userId = 1

If you remove the $em->flush()_ after _$em->persist($user); in the last example, the code works (channels are persisted).

I did not have this problem with Doctrine2 Alpha4.

@doctrinebot

Comment created by @beberlei:

What do you do in "setChannels"? Do you completly overwrite the previous content of the association variable "User::$channels" ?

@doctrinebot

Comment created by slasher:

I have reproduced the bug in a fully working example. See attachment. Just read instructions in comment and execute each step seperately.

But yes, I overwrite the previous content of the association variable "User::$channels" with a Doctrine ArrayCollection.
\

/*** @Entity @Table(name="users") **/
class User
{
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
    /*** @Column(type="string", length=50) **/
    private $name;

    /****
     * @ManyToMany(targetEntity="Channel")
     * @JoinTable(name="users_channels",
     *          joinColumns={@JoinColumn(name="userId",
                referencedColumnName="id")},
     *          inverseJoinColumns={@JoinColumn(name="channelId",
     *          referencedColumnName="id")}
     *      )
     * @var ArrayCollection
     */
    protected $channels;

    public function **construct(){
        $this->channels = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getChannels() {
        return $this->channels;
    }

    public function setChannels($channels) {
        $channels =  new \Doctrine\Common\Collections\ArrayCollection($channels);

        $this->channels = $channels;
    }
}
@doctrinebot

Comment created by @beberlei:

Fixed.

@doctrinebot

Issue was closed with resolution "Fixed"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.0.1 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
Something went wrong with that request. Please try again.