我对如何使用学说事件更新相关集合有点困惑。
一个实体通过多对多(ManyToMany)与另一个实体相关。为了更好地理解,您可以查看下面的示例(有工作的用户)。 目标是:当用户的状态将要更改时,他的工作也应该从事件监听器更改。
我已经尝试过 preUpdate
事件:
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getObject();
foreach ($entity->getJobs() as $job) {
$entity->getJobs()->removeElement($job);
}
}
还有onFlush
事件:
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
);
}
}
但是,如果仅在监听器外部更改状态 - 用户仍然拥有相同的作业(监听器中的作业未更改):
$user->setStatus('some-other-status');
但是如果集合在监听器外部发生更改 - 它可以工作(作业已从监听器更改):
$collection = ... // some new collection of jobs
$user->setJobs(collection);
欢迎任何帮助。
以下是实体的代码片段:
用户.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();
}
...
}
作业.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;
...
}
最佳答案
我建议在此任务中完全避免 Doctrine 事件监听器。相反,整个行为应该直接在用户实体中建模:setState() 方法还可以保留删除作业的行为。
然后寻找removeOrphans=true
学说映射选项:
基本上它的工作原理是删除 Job
从集合中并设置其 User
为空。 Doctrine 将从工作单元中检测到您的孤立作业,并在调用 persist($user); flush();
时自动从数据库中删除它们。
关于php - Doctrine - 更新事件监听器内的多对多关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52422588/