我有两个实体(简化):
class EncryptedMasterKey {
/**
* @ORM\ManyToOne(targetEntity="ExchangeFile", inversedBy="encryptedMasterKeys")
* @ORM\JoinColumn(name="exchange_file_id", referencedColumnName="id")
*
* @var ExchangeFile
*/
protected $exchangeFile;
}
和
class ExchangeFile {
/**
* @ORM\OneToMany(targetEntity="EncryptedMasterKey", mappedBy="exchangeFile", orphanRemoval=true, cascade={"persist", "remove"})
*/
protected $encryptedMasterKeys;
}
数据库中一个EncryptedMasterKey
可能有很多ExchangeFile
个。如果删除ExchangeFile
,则会删除所有相关的加密MasterKeys
(orphanRemoval=true
和cascade={"persist", "remove"}
以确保是这种情况)。到目前为止,非常好。
现在,当实际文件在硬盘上加密时,必须有至少一个EncryptedMasterKey
,以便可以解密文件。因此,当EncryptedMasterKey
被删除并且我发现它是ExchangeFile
的最后一个时,我还必须删除ExchangeFile
,因为它无法再被解密。如果没有至少一个ExchangeFile
,EncryptedMasterKey
就无法生存。
我如何实现这一目标? @ORM\PreRemove
课程中的EncryptedMasterKey
对我没有帮助,因为我无法访问实体管理器:
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?
}
}
这有什么优雅的解决方案吗?
感谢您的时间。
答案 0 :(得分:4)
您可以使用event subscriber并创建如下的类:
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());
}
}
}
}
您可以在the documentation上了解有关如何在Symfony 2的特定情况下注册订阅者的更多信息。