Symfony 如果子集合为空,如何删除父实体?

Symfony 如果子集合为空,如何删除父实体?,symfony,events,doctrine,Symfony,Events,Doctrine,我有两个实体:游戏和产品。游戏与产品有一对多的关系 游戏定义为 class Game { /** * @ORM\OneToMany(targetEntity=Product::class, mappedBy="game") */ private $products; } 为了在$games->getProducts()为空时删除游戏,我创建了一个onFlush侦听器。问题在于产品数量是实际应用更改之前的数量。如果我一个接一个地删除实体,这

我有两个实体:
游戏
产品
游戏
产品
有一对多的关系

游戏
定义为

class Game
{
    /**
     * @ORM\OneToMany(targetEntity=Product::class, mappedBy="game")
     */
    private $products;
}
为了在$games->getProducts()为空时删除游戏,我创建了一个onFlush侦听器。问题在于产品数量是实际应用更改之前的数量。如果我一个接一个地删除实体,这将很好,但如果我一次删除2个或多个产品,这将失败,因为我无法确认集合是空的,你知道我如何实现这一点吗

侦听器的定义如下:

class ChainDeletionListener {

    public function onFlush(OnFlushEventArgs $event): void {

        $em = $event->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityDeletions() as $entity) {
            // We check if the deleted entities are Product
            if ($entity instanceof Product) {
                /** @var Product $entity */
                $game = $entity->getGame();

                if (sizeof($game->getProducts()) === 1) {
                    // If the Product we are removing is the last one, we also remove the Game
                    $em->remove($game);
                    $uow->computeChangeSet($em->getClassMetadata(get_class($entity)), $entity);
                }
            }
        }
    }
}

谢谢你的帮助

在@OneToMany注释中,添加“cascade”属性:

类游戏
{
/**
*@ORM\OneToMany(targetEntity=Product::class,mappedBy=“game”,cascade={“persist”,“remove”})
*/
私人产品;
}

简单的方法是实际加载游戏实体及其产品集合,并移除该集合中的产品

类ChainDeletionListener{
公共函数onFlush(OnFlushEventArgs$事件):无效{
$em=$event->getEntityManager();
$uow=$em->getUnitOfWork();
foreach($uow->GetScheduleIdentityDeletes()作为$entity){
//我们检查删除的实体是否为产品
if($entity instanceof Product){
/**@var产品$entity*/
$game=$entity->getGame();
$game->removeProduct($entity);//getProducts())==0{//remove($game);
$uow->computeChangeSet($em->getClassMetadata(get_类($entity)),$entity);
}
}
}
}
}
这假设一个容错删除游戏::removeProduct(产品)实现。明显的缺点是游戏的收藏总是被加载。我看没有安全的办法


或者,您也可以使用post flush检查是否有零产品的游戏。

我相信如果删除了游戏,这将删除所有产品。我的用例是,如果我删除了与游戏关联的最后一个产品,就删除游戏。你们觉得怎么样?好吧,我明白了,我也建议在产品实体上添加注释,但我不确定它是否会修复,你们可以试试。
$game->getProducts()
是ArrayCollection吗?如果是,可能siezof()函数不是解决方案,请尝试使用
If($game->getProducts()->isEmpty())
Look:(但仅当您使用ArrayCollection for children实体时)这确实是一个ArrayCollection。我可以使用$game->getProducts()->count()代替sizeof,但返回的结果是相同的。类似地,isEmpty返回false,因为计数仍然不是0。当我查看计划删除的实体时,我看到了产品,但我可以看到$game->getProducts()不是按条令计算的。我想知道您是否需要像这样独立地获取游戏实体:
$game=$em->getRepository(game::class)->find($entity->getGame()->getId())
您是否尝试过设置“孤立删除”选项?孤立删除在这里不起作用,因为我正在尝试在不再有附加产品的情况下删除游戏。我相信OphanRemove可以自动删除不再有与之关联的游戏的产品。描述相当明确,实体已被删除所有拥有的实例都是断开连接的。因为产品是拥有方(拥有方有“inversedBy”),我宁愿假设与你所声称的完全相反。然而,当你决定使用15个字符的解决方案时,我不想强迫你使用30个字符的解决方案。我感谢你花时间回答@Jakumi,但我的理解是,如果产品与一个游戏没有链接,孤儿移除将移除任何产品(多个产品对应一个游戏),这不是我的用例。在提供的链接中,似乎许多方面都将被删除。嗯,恐怕你是对的。在这种情况下,有一种直接的方法(见答案)。