2013-10-05 62 views
2

嗨,我有一個操作,將人添加到一個組中。實體持續發現之前存在的新關係

爲了增加可用性,表格爲它刪除了已經在組中的人員。

我控制器操作是這樣的:

public function addAction(UserGroup $userGroup) 
{ 
     $tempGroup = new UserGroup(); 
     foreach ($userGroup->getUsers() as $user) { 
      $tempGroup->addUser($user); 
     } 
     $form = $this->container->get('form.factory')->create(new UserGroupQuickType(), $tempGroup); 

     $request = $this->container->get('request'); 

     if ('POST' === $request->getMethod()) { 
      $form->submit($request); 

      if ($form->isValid()) { 
       $group = $form->getData(); 

       /** @var $myUserManager UserManager */ 
       $myUserManager = $this->container->get('strego_user.user_manager'); 
       /** @var $em EntityManager */ 
       $em = $this->container->get('em'); 

       foreach ($group->getUsers() as $toInvite) { 
       $userGroup->addUser($toInvite); 
       } 
      $em->persist($userGroup); 
       $em->flush($userGroup); 

      } 
     } 

     return array(
      'form' => $form->createView(), 
      'userGroup' => $userGroup 
    ); 
} 

此代碼拋出一個異常:

A new entity was found through the relationship 'Strego\UserBundle\Entity\UserGroup#users' 
that was not configured to cascade persist operations for entity: Degi. 
To solve this issue: Either explicitly call EntityManager#persist() on 
this unknown entity or configure cascade persist this 
association in the mapping for example @ManyToOne(..,cascade={"persist"}). 

與新發現的關係已經在那裏了。意思是用戶「Degi」已經在組中,並且不是新的實體。

我可以避免這個錯誤,如果我留下堅持,但然後我會得到一個異常:Entity has to be managed or scheduled for removal for single computation

這是由以下事實引起的我的「用戶組」實體具有的全部時間爲3的實體狀態(=分離的)

我已經使用相同的邏輯(具有臨時基等)用於實體與我的用戶組有1對1的關係,並且從那裏我可以輕鬆地將人員添加到組中。 但是這並不符合邏輯上完成同樣的事情。

更新: 我以前的更新是在錯誤的方向領先。但在這裏比較(幾乎)相同的控制器,該控制器的工作原理:

public function addAction(BetRound $betRound) 
    { 

     $userGroup = new UserGroup(); 
     foreach ($betRound->getUsers() as $user) { 
      $userGroup->addUser($user); 
     } 
     $form = $this->createForm(new UserGroupQuickType(), $userGroup); 

     $request = $this->getRequest(); 

     if ('POST' === $request->getMethod()) { 

      $form->submit($request); 
      if ($form->isValid()) { 
       /** @var $betRoundManager BetRoundManager */ 
       $betRoundManager = $this->container->get('strego_tipp.betround_manager'); 
       /** @var $myUserManager UserManager */ 
       $myUserManager = $this->container->get('strego_user.user_manager'); 

       $group = $form->getData(); 

       foreach ($group->getUsers() as $toInvite) { 
        if (!$betRound->getUserGroup()->hasUser($toInvite)) { 
         $betRound->getUserGroup()->addUser($toInvite); 
        } 
       } 
       $this->getDoctrine()->getManager()->flush(); 
       return $this->redirect($this->generateUrl('betround_show', array('id' => $betRound->getId()))); 
      } 
     } 

     return array(
      'form' => $form->createView(), 
      'betRound' => $betRound 
     ); 
    } 

回答

0

這是預期的行爲,因爲你有關係,不是一個真正的新的實體,但非託管對象。

在迭代時,您可以嘗試合併$toInvite。不用擔心,如果通過表單獲取的對象具有適當的標識符(@Id)值集,則它們只會從數據庫重新加載,而不是標記爲插入。另一方面,新添加的對象將被標記。

因此,在嘗試任何事情之前,請確保每個舊$toInvite都有一個ID集。

foreach ($group->getUsers() as $toInvite) { 
    $em->merge($toInvite); 
    $userGroup->addUser($toInvite); 
} 
// safe to do now, all of the added users are either reloaded or marked for insertion 
$em->perist($usetGroup); 
$em->flush($userGroup); 

希望這會有所幫助。

+0

問題是,「新」找到的實體不是「toInvite」之一,而是其中一箇舊的。那麼我是否也必須合併所有現有的? – m0c

0

發生這種情況的原因是$userGroup已經是一個已經存在的實體,而$toInvite是一個新實體,您正試圖刷新$userGroup。爲了使這個代碼正常工作,你需要在你的實體文件中指定cascade={"persist"}(Annotations或yaml,無論你喜歡什麼)。

其他的解決辦法是做反向,堅持$toInvite

foreach ($group->getUsers() as $toInvite) { 
    $toInvite->setUserGroup($userGroup); 
    $em->persist($toInvite); 
} 
$em->flush(); 

我認爲第一種選擇將是一個更好的選擇

+0

$ toInvite也是一個已經存在的實體。它是一個現有的用戶。我只是從該組添加一個關係到用戶。這就是爲什麼我認爲這將足以更新用戶組 – m0c

+0

在這種情況下'cascade = {「persist」}應該可以解決您的問題 –

+0

如果我堅持toInvite它會拋出一個異常,因爲toInvite不被識別爲已經現有的實體和我的然後它由於唯一的限制而失敗,因爲教條要求添加一個新的條目與現有的數據相同。 – m0c

0

幾次嘗試之後,我發現這個問題實際上是2個問題: 1.我有一位聽衆,即使沒有必要,也能堅持更新一些行。2. paramconverter以某種方式分離正在進入的實體。這意味着我的UserGroup和其中的所有用戶都已分離。只要再次將它們添加到用戶組,這些實體似乎對於EM而言是「新的」。因此,我需要合併所有用戶,並修復更新「createdBy」的偵聽器,否則這將需要合併。

相關問題