2016-08-25 111 views
0

我有一個使用下面的協會等實體的孩子一個FileUpload實體時刪除家長協會:主義 - 刪除子記錄

/** 
    * @ORM\ManyToOne(targetEntity="FileUpload", cascade={"persist", "remove"}) 
    * @ORM\JoinColumn(name="image_id", referencedColumnName="id") 
    */ 
    protected $image; 

的文件上傳實體包含上傳文件的各種信息,以及一個布爾字段將其標記爲刪除(由表單上的複選框處理)。我試圖找到一種管理此刪除過程的好方法,而不必在具有FileUpload實體的每個實體中複製代碼。

我試着創建一個標記爲doctrine.event_listener的服務來刪除postUpdate()中的FileUpload,但是因爲仍然存在與FileUpload的父級關聯,所以失敗了。有沒有人知道清除與FileUpload的任何關聯的方式,當它被刪除?或者其他任何處理這個過程的方法?

+0

ManyToOne是否正確?你想要許多與1個文件上傳相關的實體? –

+0

我問上一個問題,因爲這意味着FileUpload是關係的所有者,所以當其他實體被刪除時不應該被刪除,因爲可能有更多與該文件上傳相關的內容。 –

+0

你說得對,每個實體只有一個FileUpload。我使用ManyToOne是因爲我的印象是你不能在同一個表上有多個OneToOne關聯?例如,我有多個不同的實體,都具有FileUpload關聯,如果所有這些都是OneToOne,那麼這樣做會起作用嗎? – dk80

回答

1

對不起,遲到的答案。現在我明白你的問題了。

在你描述的關係中的關係必須是關係的所有者。如果讓我們說A與B有關,並且假設A是關係的所有者,那就意味着A控制了關係的所有方面,所以如果沒有這麼說,B就不能被刪除。

想一想數據庫的外鍵關係。只要數據庫是關係的一部分並且不是關係的所有者(這是您當前的問題),數據庫不會讓您刪除該行。

如果您進入某個地方需要刪除FileUpload而不知道與其關聯的註釋,那麼您的應用程序/數據庫設計中可能存在體系結構問題。如果您知道與要上傳文件的FileUpload相關的Comment,那麼orphanRemoval就是您需要的。您刪除它的方式不是要求經理將其刪除(因爲在未經關係所有者批准的情況下無法執行此操作(如上例所述)。相反,你問的關係的所有者刪除它是這樣的

//for OneToOne relation 
$comment->setFileUpload(null); 

//for OneToMany relation 
$comment->getFileUpload()->removeElement($fileUpload); 

上述聲明呼籲沖洗之後,它應該工作。也爲一對多確保您在評論實體構造函數中初始化

$this->fileUpload = new ArrayCollection(); 

注1:正如前面提到的,謹慎使用孤兒刪除功能會導致它無法正常工作,因爲您會預期與管理器的刷新功能有關。當一個對象以孤兒的形式在工作單位中上市時,即使您對其進行了刷新,或者它是父項,它也會被刪除。找到一個解決這個問題的方法(使用onFlush事件的教條),但最好不要這樣做,並儘量避免這種情況。

注意2:orphanRemoval在數據庫中具有硬刪除的效果。如果因爲某些時候,你需要做的這個代碼添加到教義用戶或onFlush聽衆

public function onFlush(OnFlushEventArgs $args) 
{ 
    foreach ($args->getEntityManager()->getUnitOfWork()->getScheduledEntityDeletions() as $entity) { 

     if ($entity instanceof SoftRemovableInterface) { 
      $args->getEntityManager()->remove($entity); 
      $args->getEntityManager()->persist($entity); 
      $entity->remove(); 
     } 

     $args->getEntityManager()->getUnitOfWork()->computeChangeSet($args->getEntityManager()->getClassMetadata(get_class($entity)), $entity); 
    } 
} 

凡刪除+持續通話有沒有采取實體出來的孤兒刪除列表中的工作單元(的一部分在NOTE1中刷新實體的修復,這是唯一的地方,唯一的辦法,我發現你可以停止刪除一個孤兒後,它被標記爲這樣的教條),和$實體 - >刪除();是處理軟刪除的SoftRemovableInterface的方法,類似於

class Comment implements SoftRemovableInterface 
{ 
    /........../ 
    function remove() 
    { 
     $this->deleted = true; 
    } 
} 

希望這會爲您的問題帶來一些亮點。快樂的編碼。

Alexandru Cosoi

+0

感謝您的詳細解釋。非常感激。 – dk80