Doctrine2 ne respecte pas l'ordre des opérations sur les collections?
Bonjour,
Effet recherché:
1. vider une collection doctrine (One-to-many)
Code:
$myEvent->getRegistrations()->clear()
2. ajouter de nouveaux membres à cette collection
Code:
$myEvent->addRegistration($myRegistration)
3. enregistrer en base de donnée:
Code:
$em->persist($myEvent); $em->flush();
Constatation:
Après de nombreux essais, lors du flush final, l'insertion de la nouvelle Registration se fait avant le delete des autres Registrations de la collection.
Apparemment, doctrine2 ne respecte pas l'ordre dans lequel sont effectuées ces opérations si on ne met qu'un seul flush à la fin (en 3), et il faut mettre en plus un flush entre 1) et 2) pour que ça fonctionne.
Question:
Est-ce que ma constation est juste?
Mais dans ce cas, est-ce qu'il ne serait pas logique que doctrine gère ce worflow de façon transparente, et réalise les opérations dans le bonne ordre lors du flush en 3) ?
Détail de mon test:
- Mes relations: Event <= One-to-Many => Registrations <=Many-to-One => User
- Ma DB contient déjà des Registrations pour l'Event traité ici
- j'ai une contrainte Unique sur la propriété User de mes entités Registration (colonne event_user)
- Raison pour laquelle je souhaite avoir qu'un seul flush: pendant que je travaille sur l'entité en mémoire, je souhaite par la suite faire un detach pour récupérer l'ancienne entité dans la base et examiner les différences entre l'ancienne et la nouvelle.
Avec le code suivant, j'obtiens une exception due à la violation sur la clef étrangère user, ce qui indique que les Registrations n'ont pas été supprimées en base de donnée avant l'insertion (la base de donnée contient déjà des Registrations, dont une pour l'utilisateur 1 que j'ajoute aprés):
Citation:
An exception occurred while executing 'INSERT INTO Registration (createdAt, updatedAt, numparticipant, numqueuedparticipant, organizer, user_id, event_id) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["2014-07-12 20:32:26", "2014-07-12 20:32:26", 10, 0, 1, 1, 114]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '114-1' for key 'event_user'
Définition de la relation:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
Cpt\EventBundle\Entity\Event:
type: entity
oneToMany:
registrations:
targetEntity: Registration
mappedBy: event
indexBy: user_id
cascade: ["persist","detach","merge"]
orphanRemoval: true
Cpt\EventBundle\Entity\Registration:
type: entity
event:
targetEntity: Event
inversedBy: registrations
joinColumn:
name: event_id
referencedColumnName: id
onDelete: CASCADE |
Voilà mon code de test:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
public function testAction()
{
try{
// Récupérer l'Event 114 déjà en base de donnée
$event = $this->getEventManager()->getEventById(114);
// Supprimer toutes les registrations (j'ai essayé avec la boucle foreach mais sans le collection->clear() et inversement, et avec les deux
foreach($event->getRegistrations() as $registration){
$event->removeRegistration($registration);
$this->getDoctrine()->getManager()->remove($registration);
}
$event->getRegistrations()->clear();
// Persist l'Event - J'ai essayé avec et sans ce persist
$this->getDoctrine()->getManager()->persist($event);
// Créer une nouvelle Registration et l'ajouter à la collection
$user = $this->getUserManager()->findUserBy(Array("id" => 1));
$registration = $this->getRegistrationManager()->CreateRegistration($event, $user, 10, true );
$event->addRegistration($registration);
// Persist et Flush l'Event
$this->getDoctrine()->getManager()->persist($event);
$this->getDoctrine()->getManager()->flush();
} catch (\Exception $e) {
throw $e;
}
} |
le removeRegistration de l'entité event:
Code:
1 2 3 4 5 6
|
public function removeRegistration(\Cpt\EventBundle\Entity\Registration $registrations)
{
$this->registrations->removeElement($registrations);
$registrations->setEvent(null);
} |