Doctrine orm “信条”;反向;孤儿切除

Doctrine orm “信条”;反向;孤儿切除,doctrine-orm,Doctrine Orm,我有两个实体(简化): 及 数据库中一个ExchangeFile可以有多个EncryptedMasterKeys。如果删除了ExchangeFile,则会删除所有相关的加密MasterKey(OrphanRemoving=true和cascade={“persist”,“remove”}确保情况属实)。到目前为止,一切顺利 现在,由于实际文件在硬盘上进行了加密,因此必须至少有一个EncryptedMasterKey,才能对文件进行解密。因此,当删除EncryptedMasterKey时,我发现它

我有两个实体(简化):

数据库中一个
ExchangeFile
可以有多个
EncryptedMasterKey
s。如果删除了
ExchangeFile
,则会删除所有相关的加密
MasterKey
OrphanRemoving=true
cascade={“persist”,“remove”}
确保情况属实)。到目前为止,一切顺利

现在,由于实际文件在硬盘上进行了加密,因此必须至少有一个
EncryptedMasterKey
,才能对文件进行解密。因此,当删除
EncryptedMasterKey
时,我发现它是
ExchangeFile
的最后一个密钥,我还必须删除
ExchangeFile
,因为它不能再解密了。
ExchangeFile
如果没有至少一个
EncryptedMasterKey
就无法生存

我如何做到这一点<
EncryptedMasterKey
类中的code>@ORM\PreRemove对我没有帮助,因为我没有访问实体管理器的权限:

class EncryptedMasterKey {
    //...
    /** @ORM\PreRemove */
    public function removeOrphanExchangeFile()
    {
        if ($this->exchangeFile->isTheOnlyMasterKey($this))
            // I don't have access to the Entity Manager,
            // so how do I delete the ExchangeFile?
    }
}
有什么优雅的解决办法吗

感谢您的时间。

您可以使用并创建如下类:

class MyEncryptedMasterSubscriber implements \Doctrine\Common\EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(\Doctrine\ORM\Events::onFlush);
    }

    public function onFlush(\Doctrine\ORM\Events\OnFlushEventArgs $eventArgs)
    {
        $uow = $eventArgs->getEntityManager()->getUnitOfWork();


        foreach ($uow->getScheduledEntityDeletions() AS $entity) {
            if (
                $entity instanceof EncryptedMasterKey 
                && $entity->getExchangeFile()->isTheOnlyMasterKey($entity)
            ) {
                $uow->scheduleForDelete($entity->getExchangeFile());
            }
        }
    }
}

您可以阅读更多关于如何在Symfony 2 on的特定情况下为其注册订户的信息。

这就是方法。非常感谢奥克拉米乌斯!这个解决方案似乎有一个特别的问题:如果我试图访问加密的主密钥集合(
$this->getEncrpytedMasterKeys()
,在
ExchangeFile
中),集合(
PersistentCollection
)将不再初始化。因此,该
交换文件
似乎没有
EncryptedMasterKey
(尽管实际上有)。在该事件发生之前,集合已初始化。当我处于
onFlush
事件中时,为什么持久集合不再初始化?@to0om持久集合只初始化一次。您是否验证了它是否尚未初始化?它尚未初始化,因为在执行侦听器之前(在该特定情况下),尚未调用
$exchangeFile->getEncryptedMasterKeys()
)。在任何其他情况下,当我调用
$exchangeFile->getEncryptedMasterKeys()
时,
getIterator()
,因此在
PersistentCollection
中调用
initialize()
。我只是无法解释为什么它在这种情况下不起作用。
class EncryptedMasterKey {
    //...
    /** @ORM\PreRemove */
    public function removeOrphanExchangeFile()
    {
        if ($this->exchangeFile->isTheOnlyMasterKey($this))
            // I don't have access to the Entity Manager,
            // so how do I delete the ExchangeFile?
    }
}
class MyEncryptedMasterSubscriber implements \Doctrine\Common\EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(\Doctrine\ORM\Events::onFlush);
    }

    public function onFlush(\Doctrine\ORM\Events\OnFlushEventArgs $eventArgs)
    {
        $uow = $eventArgs->getEntityManager()->getUnitOfWork();


        foreach ($uow->getScheduledEntityDeletions() AS $entity) {
            if (
                $entity instanceof EncryptedMasterKey 
                && $entity->getExchangeFile()->isTheOnlyMasterKey($entity)
            ) {
                $uow->scheduleForDelete($entity->getExchangeFile());
            }
        }
    }
}