que tienen esta entidad:¿Cómo actualizar una colección manyToMany de una entidad en onFlush event listener?
<?php
namespace Comakai\MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM,
Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
*/
class Stuff {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $content;
/**
* @ORM\ManyToMany(targetEntity="Apple", cascade={"persist"})
*/
private $apples;
/**
* @ORM\ManyToMany(targetEntity="Pig")
*/
private $pigs;
public function __construct() {
$this->apples = new \Doctrine\Common\Collections\ArrayCollection();
$this->pigs = new \Doctrine\Common\Collections\ArrayCollection();
}
public function setApples($apples) {
$this->getApples()->clear();
foreach ($apples as $apple) {
$this->addApple($apple);
}
}
public function setPigs($pigs) {
$this->getPigs()->clear();
foreach ($pigs as $pig) {
$this->addPig($pig);
}
}
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* Set content
*
* @param text $content
*/
public function setContent($content) {
$this->content = $content;
}
/**
* Get content
*
* @return text
*/
public function getContent() {
return $this->content;
}
/**
* Add apples
*
* @param Comakai\MyBundle\Entity\Apple $apples
*/
public function addApple(\Comakai\MyBundle\Entity\Apple $apples) {
$this->apples[] = $apples;
}
/**
* Get apples
*
* @return Doctrine\Common\Collections\Collection
*/
public function getApples() {
return $this->apples;
}
/**
* Add pigs
*
* @param Comakai\MyBundle\Entity\Pig $pigs
*/
public function addPig(\Comakai\MyBundle\Entity\Pig $pigs) {
$this->pigs[] = $pigs;
}
/**
* Get pigs
*
* @return Doctrine\Common\Collections\Collection
*/
public function getPigs() {
return $this->pigs;
}
}
y esto oyente:
<?php
namespace Comakai\MyBundle\Listener;
use Comakai\MyBundle\Util\SluggerParser
Doctrine\ORM\Event\OnFlushEventArgs,
Comakai\MyBundle\Entity\Stuff,
Comakai\MyBundle\Entity\Apple,
Comakai\MyBundle\Entity\Pig;
class Listener {
/**
* @param \Doctrine\ORM\Event\OnFlushEventArgs $ea
*/
public function onFlush(OnFlushEventArgs $ea) {
$em = $ea->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityInsertions() AS $entity) {
$this->save($entity, $em, $uow);
}
foreach ($uow->getScheduledEntityUpdates() AS $entity) {
$this->save($entity, $em, $uow);
}
}
public function save($entity, $em, $uow) {
if ($entity instanceof Stuff) {
$pigRepository = $em->getRepository('Comakai\MyBundle\Entity\Pig');
$content = $entity->getContent();
preg_match_all('/@@ pig:(\d+) @@/i', $content, $matches);
$entity->getPigs()->clear();
foreach($matches[1] as $pigID) {
$pig = $pigRepository->find($pigID);
if(!empty($pig)) {
$entity->addPig($pig);
}
}
$entity->setContent($content);
$meta = $em->getClassMetadata(get_class($entity));
$uow->recomputeSingleEntityChangeSet($meta, $entity);
$uow->computeChangeSet($meta, $entity);
}
}
}
y funciona bien si la recolección de la manzana está vacía, pero si tiene algún elemento que conseguir un error de duplicación.
¿Cómo puedo saber a la UnitOfWork que sólo quiero volver a calcular la colección del cerdo?
ACTUALIZACIÓN
Hay un nuevo evento de pre-limpieza (https://github.com/doctrine/doctrine2/pull/169) y creo que este tipo de cosas se pueden hacer allí. ¡Ese RP no está en la rama que estoy usando, pero intentémoslo!
Lo sentimos, pero el pre-limpieza resolvió mi problema. Modificar el UoW es una especie de piratería y muy desordenado, puede volverte loco con las colecciones. – coma
Coma, estoy de acuerdo. Tu pregunta era sobre hacer cosas en onFlush(), y esta es la única forma de hacerlo. Si su caso de uso puede implementarse en preFlush(), ¡eso es genial! – jmlnik
Bueno ... parece que el evento preFlush tan esperado hace casi cualquier cosa ... todas las listas programadas están vacías. – coma