我有以下Doctrine实体设置:
class MainEntity
{
/**
* @var SecondEntity[]
*
* @ORM\OneToMany(targetEntity="SecondEntity", mappedBy="mainEntity", cascade={"persist"})
*/
private $secondEntities;
/**
* @var integer
*
* @ORM\Column(type="integer", nullable=false, name="second_entities_count")
*/
private $secondEntitiesCount;
...
}
class SecondEntity
{
/**
* @var MainEntity
*
* @ORM\ManyToOne(targetEntity="MainEntity", inversedBy="secondEntities")
* @ORM\JoinColumn(name="main_entity_id", referencedColumnName="id", nullable=false)
*/
private $mainEntity;
...
}
创建或删除SecondEntity
时,我希望相关$secondEntitiesCount
中的MainEntity
进行相应更新。
为实现这一目标,我创建了一个onFlush
订阅者,该订阅者收集SecondEntity
个对象的所有预定删除和插入
$delsertions = array_merge(
$unitOfWork->getScheduledEntityInsertions(),
$unitOfWork->getScheduledEntityDeletions()
);
foreach ($delsertions as $entity) {
if ($entity instanceof SecondEntity) {
$mainEntity = $entity->getMainEntity();
$mainEntityMeta = $em->getClassMetadata(MainEntity::class);
$unitOfWork->recomputeSingleEntityChangeSet($mainEntityMeta, $mainEntity);
dump($mainEntity->getSecondEntities); // The creation/deletion of the current entity is not reflected here!
}
}
问题在于,在上面的dump()
中,在创建/删除触发订阅者的实体后,集合尚未相应更新。例如,如果我为给定的SecondEntity
创建第一个MainEntity
,则$secondEntities
集合将为空。
如果我删除唯一的SecondEntity
,则$secondEntities
集合中仍会包含该对象。
在这种情况下,recomputeSingleEntityChangeSet()
电话似乎无能为力。
如何强制正确更新集合?
答案 0 :(得分:0)
你可以创建一个这样的监听器:
use Doctrine\ORM\Event\LifecycleEventArgs;
class UpdateMainListener
{
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
// only act on "SecondEntity" entity
if (!$entity instanceof SecondEntity) {
return;
}
$main = $entity->getMainEntity();
if(!is_null($main))
$main->increaseSecondEntitiesCount();
}
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
// only act on "SecondEntity" entity
if (!$entity instanceof SecondEntity) {
return;
}
$main = $entity->getMainEntity();
if(!is_null($main))
$main->decreaseSecondEntitiesCount();
}
}
然后设置服务:
mybundle.prepersist.listener:
class: MyBundle\EventListener\UpdateMainListener
tags:
- { name: doctrine.event_listener, event: prePersist }
mybundle.preremove.listener:
class: MyBundle\EventListener\UpdateMainListener
tags:
- { name: doctrine.event_listener, event: preRemove }