【问题标题】:Update collection of a related entity with the newly created/deleted object (onFlush)使用新创建/删除的对象 (onFlush) 更新相关实体的集合
【发布时间】:2016-11-08 18:48:41
【问题描述】:

我有以下 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 时,我希望相关MainEntity 中的$secondEntitiesCount 相应更新。

为了实现这一点,我创建了一个 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() 中,在创建/删除触发订阅者的实体之后,集合并没有相应地更新。例如,如果我为给定的MainEntity 创建第一个SecondEntity,则$secondEntities 集合将为空。 如果我要删除唯一的SecondEntity$secondEntities 集合中仍会包含该对象。 在这种情况下,recomputeSingleEntityChangeSet() 调用似乎没有任何作用。

如何强制正确更新集合?

【问题讨论】:

    标签: symfony doctrine-orm doctrine


    【解决方案1】:

    你可以像这样创建一个监听器:

    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 }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多