2013-07-26 40 views
1

我有一個導入腳本,它讀出一個XML文件並將數據添加到MySQL數據庫。 xml文件包含匹配數據和關聯的事件。學說 - 刪除並立即添加實體到ArrayCollection

我有以下實體

  • MatchList(不是最好的名字,但其他話題)
  • MatchEvent

我的問題的相關關係:

內MatchList(反面)

/** 
* @OneToMany(targetEntity="MatchEvent", mappedBy="match", orphanRemoval=true) 
*/ 
private $events; 

public function __construct($uId) 
{ 
    $this->setId($uId); 
    $this->events = new ArrayCollection(); 
} 

內MatchEvent(持有端)

/** 
* @ManyToOne(targetEntity="MatchList", inversedBy="events") 
* @JoinColumn(name="match_id", referencedColumnName="id") 
*/ 
private $match; 

裏面的進口腳本我有每場比賽一個循環。在循環內我想刪除當前分配給該匹配的所有事件。之後我想從xml文件中添加新的事件到這個匹配。

事件應該從數據庫中完全刪除。不僅是對比賽的參考。

一個簡單的例子

XML的內容

Match1 
    EventA 
    EventC 
    EventF 

導入之前

Match1 
    EventA 
    EventB 

導入之後,它應該是這樣的

Match1 
    EventA 
    EventC 
    EventF 

這樣的事件可能是

  • delete + add(EventA)。
  • 刪除(EventB)
  • 加(EventF)

這是因爲XML包含了事件更新或修正。 因此,唯一可靠的方法是刪除所有分配的事件並添加最新xml中的當前有效事件。

我的問題是刪除部分配合馬上添加。它自己的每個任務都在工作。

我嘗試了不同的方法(也閱讀教條文檔),但我無法得到它的工作。

繼腳本的一些變種,我試圖(註釋掉) 相關的部分(不是全部的代碼,看看「......」我希望這是不夠了解我的問題/錯誤)

try 
{ 
    foreach($matches as $matchNode) 
    { 
     $match = new \MatchList($matchNode['uID']); 
     ... 
     $previousEvents = $match->getEvents(); 
     foreach($previousEvents as $previousEvent) 
     { 
      $match->removeEvent($previousEvent); 
      //$previousEvent->setMatch(null); 
      //$this->em->remove($previousEvent); 
      //$this->em->persist($previousEvent); 
     } 

     foreach($teamData->Goal as $goal) 
     { 
      ... 
      $event = new \MatchEvent($match); 
      $event->setPlayer($player); 
      $event->setType($goal['Type']); 
      $event->setPeriod($goal['Period']); 

      $this->em->persist($event); 
      $match->addEvent($event); 
     } 
     ... 
     $this->em->persist($match); 
    } 
    $this->em->flush(); 
} 
catch(Exception $e){} 

無論我嘗試了什麼,它都沒有按預期工作。有時候我會遇到一個錯誤(Missing cascade persist)或者沒有錯誤發生,但也沒有刪除。只有當我一次執行一項任務(刪除或添加)時纔有效。

我知道只對反面進行的更改不會被教條保存,所以我嘗試調用MatchEvent實體上的remove。或試圖取消設置整個ArrayCollection,並使用orphanRemoval刪除實體。

我一直在努力嘗試。 我希望有人能幫助我理解我做錯了什麼,以及正確的方式。

謝謝

編輯

也許是有益的補充每次變化我試過。

變體1)

不正確之後添加實體:從DB(GOOD刪除事件)

右後添加實體:ERROR:一個新的實體是通過關係「MatchList#事件發現'沒有被配置爲爲實體級聯持久化操作:MatchEvent @ XYZ。 (BAD)

$previousEvents = $match->getEvents(); 
foreach($previousEvents as $previousEvent) 
{ 
    $this->em->remove($previousEvent); 
} 

變2)

不正確之後添加實體:ERROR:權之後,從DB(GOOD刪除事件)

與地址實體一個新的實體是通過發現未配置爲級聯持久化操作的關係'MatchList#events':實體:MatchEvent @ XYZ。 (BAD)

$previousEvents = $match->getEvents(); 
foreach($previousEvents as $previousEvent) 
{ 
    $previousEvent->setMatch(null); 
    $this->em->remove($previousEvent); 
    $this->em->detach($previousEvent); 
} 

變3)

不正確之後添加實體:錯誤:一個新的實體是通過關係,結果發現沒有配置級聯「MatchList#事件」持續實體操作:MatchEvent @ XYZ。 (BAD)

添加實體之後:未嘗試,因爲即使刪除沒有工作。

$previousEvents = $match->getEvents(); 
foreach($previousEvents as $previousEvent) 
{ 
    $previousEvent->setMatch(null); 
    $this->em->detach($previousEvent); 
} 

這應該工作或我missunderstood這樣的: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/faq.html#i-call-clear-on-a-one-to-many-collection-but-the-entities-are-not-deleted

變4)

沒有之後添加實體:因爲沒有事件已被刪除的DB雙倍的數據,所有的事件的其他用match_id NULL插入。 (BAD)

添加實體之後:未嘗試,因爲即使刪除沒有工作。

$previousEvents = $match->getEvents(); 
foreach($previousEvents as $previousEvent) 
{ 
    $previousEvent->setMatch(null); 
    $this->em->detach($previousEvent); 
    $this->em->persist($previousEvent); 
} 

回答

2

我找到了解決辦法。

對於此解決方案,添加「orphanRemoval = true」很重要。

/** 
* @OneToMany(targetEntity="MatchEvent", mappedBy="match", orphanRemoval=true) 
*/ 
private $events; 

在循環中,我使用removeElement從ArrayCollection中刪除每個實體。由於orphanRemoval爲真,該實體也被刪除。

foreach($match->getEvents() as $event) 
{ 
    $match->getEvents()->removeElement($event); 
} 

實體的添加與上面顯示的相同。

我希望解釋可以幫助其他人解決同樣的問題。