Details
Description
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:
This works
// 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();
This also works
// 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();
This does not work (channels are removed)
// 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.
Issue Links
- is duplicated by
-
DDC-983
Creating new collection for manyToMany results in loss of data with multiple flushes
-
What do you do in "setChannels"? Do you completly overwrite the previous content of the association variable "User::$channels" ?