【发布时间】:2022-01-02 13:29:48
【问题描述】:
这是关于 Doctrine 中事件系统的问题(在 Symfony 项目中)。
我有两个类,用户和访问,它们通过多对多关系关联。 IE。一个用户可以有很多次访问,一次访问可以有很多用户(参加访问)。
class Visit
{
#[ORM\Column]
protected string $Date;
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: "Visits")]
#[ORM\JoinTable(name: "users_visits")]
protected Collection $Users;
public function __construct()
{
$this->Users = new ArrayCollection();
}
//... other properties and methods omitted
}
class User
{
#[ORM\Column]
protected string $Name;
#[ORM\ManyToMany(targetEntity: Visit::class, inversedBy: "Users")]
#[ORM\JoinTable(name: "users_visits")]
protected Collection $Visits;
public function __construct()
{
$this->Visits = new ArrayCollection();
}
//... other properties and methods omitted
}
我还有一个 UpdateSubscriber,它应该在单独的 sql 表中记录某些插入、更新或删除,以便稍后创建所有相关更改的概览。
class UpdateSubscriber implements EventSubscriberInterface
{
public function __construct(private LoggerInterface $logger)
{
}
public function getSubscribedEvents(): array
{
return [
Events::preUpdate,
Events::postPersist,
Events::postRemove,
Events::postFlush
];
}
public function preUpdate(PreUpdateEventArgs $args): void
{
$this->logger->debug('Something has been updated');
if($args->hasChangedField('Date')){
$this->logger->debug('The date has been changed.');
}
if($args->hasChangedField('Users')){
$this->logger->debug('It was the Users field');
}
}
// ... other methods emitted
我已经让这个系统工作了,但是当我运行这个测试代码时
$visitRepo = $this->om->getRepository(Visit::class);
$userRepo = $this->om->getRepository(User::class);
// you can assume that visit 7 and user 8 already exist in the database
$v = $visitRepo->find(7);
$u = $userRepo->find(8);
$v->setDate('2022-01-05');
$this->om->flush();
$v->addUser($u);
$this->om->flush();
测试代码正常工作,我可以在 sql 表“users_visits”中看到一个新行。我还可以看到访问 7 的日期已更改为 2022-01-05。
但是:查看日志我只能找到
Something has been updated.
The date has been changed.
Something has been updated.
没有“这是用户字段”。使用我的调试工具,我可以看到 EntityChangeSet 在 $v->addUser($u) 期间的 preUpdate() 期间为空,这很奇怪且出乎意料。
我已经广泛阅读了docs for the event PreUpdate,但没有提及为什么对关联集合的更改未显示在 EntityChangeSet 中,或者我如何在 EventSubscriber 中跟踪这些更改。
在 onFlushEvent 期间我是否必须通过相当繁琐的 UnitOfWork?或者这是我错过了什么?
【问题讨论】:
标签: php symfony doctrine-orm doctrine