I`m a little bit confused with how to update related collection using doctrine events.
One entity is related with another through ManyToMany. For better understanding u can see examples below (User with Jobs). The goal is: when User`s status is going to be changed then his jobs should also be changed from event listener.
I have already tried preUpdate
event:
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getObject();
foreach ($entity->getJobs() as $job) {
$entity->getJobs()->removeElement($job);
}
}
And also onFlush
event:
public function onFlush(OnFlushEventArgs $eventArgs)
{
$em = $eventArgs->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
foreach ($entity->getJobs() as $job) {
$entity->getJobs()->removeElement($job);
}
$em->persist($entity);
$uow->recomputeSingleEntityChangeSet(
$em->getClassMetadata(Job::class),
$entity
);
}
}
But in case when only status was changed outside the listener - user still have the same jobs(jobs were not changed from listener):
$user->setStatus('some-other-status');
But in case when collection was changed outside the listener - it works(jobs were changed from listener):
$collection = ... // some new collection of jobs
$user->setJobs(collection);
Any help is welcome.
Here are code snippets of entities:
User.php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity()
* @ORM\Table()
*/
class User
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $status;
/**
* @ORM\ManyToMany(targetEntity="Job")
* @ORM\JoinTable(name="_user_x_job",
* joinColumns={@ORM\JoinColumn(name="user", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={@ORM\JoinColumn(name="job", referencedColumnName="id", onDelete="CASCADE")}
* )
*/
protected $jobs;
public function __construct()
{
$this->jobs = new ArrayCollection();
}
...
}
Job.php:
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity()
* @ORM\Table()
*/
class Job
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
...
}