使用新创建/删除的对象更新相关实体的集合(onFlush)

问题描述 投票:0回答:1

我有以下教义实体设置:

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()
调用似乎没有执行任何操作。

如何强制正确更新集合?

php symfony doctrine-orm doctrine
1个回答
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 }
© www.soinside.com 2019 - 2024. All rights reserved.