2016-09-15 59 views
1

很抱歉的標題,我不知道怎麼說了。LifecycleCallback稱爲ArrayCollection的

我有兩個Entity:菌株對管一個一對多的關係,以及級聯= {「堅持」,「刪除」}屬性。 對於兩次實體我定義上有PrePersist回調飛他們的名字。但是,這隻適用於Tube實體,在Strain實體上我有一個問題,因爲它的名字是在第一個管道名稱上定義的。我認爲PrePersist在Tubes之前應用於應變。那麼如果Tubes沒有名字,那麼Strain的名字就是空的。

如果我做一個foreach而在控制器堅持一個各管一個堅持之前的應變,它工作正常。但我不太喜歡它。我們可以在某處配置它嗎,比如PrePersist的優先順序?

我的實體:

class Tube 
{ 
    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Strain", inversedBy="tubes") 
    */ 
    private $gmoStrain; 

    ... 


    // SETTERS & GETTERS 

    public function setStrain(Strain $strain) 
    { 
    $this->strain = $strain; 

    return $this; 
    } 

    public function getStrain() 
    { 
    return $this->strain; 
    } 

    ... 

    //LifecycleCallback 

/** 
* Before persist. 
* 
* @ORM\PrePersist() 
*/ 
public function prePersist() 
{ 
    // Give a name to the tube 
    // The name is composed like this: 
    // ProjectPrefix_BoxLetter_xxxType 

    // ProjectPrefix (The prefix of the first Tube) 
    $projectPrefix = $this->getBox()->getProject()->getPrefix(); 

    // BoxLetter (idem, the first tube) 
    $boxLetter = $this->getBox()->getBoxLetter(); 

    // In array the first cell is 0, in real box, it's 1 
    $cell = $this->cell + 1; 

    // Adapt the boxCell like: 1 => 001, 10 => 010, 100 => 100, never more than 999 
    if ($cell < 10) { 
     $boxCell = '00'.$cell; 
    } elseif ($cell > 99) { 
     $boxCell = $cell; 
    } else { 
     $boxCell = '0'.$cell; 
    } 

    // Type Letter 
    $lastLetter = $this->getStrain()->getType()->getLetter(); 

    // Generate the tube name 
    $this->name = $projectPrefix.'_'.$boxLetter.$boxCell.$lastLetter; 
} 
} 

應變:

class Strain 
{ 
    /** 
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Tube", mappedBy="strain", cascade={"persist", "remove"}) 
*/ 
    private $tubes; 

    ... 

    //SETTERS & GETTERS 

    public function addTube(Tube $tube) 
    { 
     if (!$this->tubes->contains($tube)) { 
      $tube->setGmoStrain($this); 
      $this->tubes->add($tube); 
     } 
    } 

    public function removeTube(Tube $tube) 
    { 
     if ($this->tubes->contains($tube)) { 
      $this->tubes->removeElement($tube); 
     } 
    } 

    public function getTubes() 
    { 
     return $this->tubes; 
    } 

    ... 

    //LifecycleCallback 

/** 
* Before persist. 
* 
* @ORM\PrePersist() 
*/ 
public function postPersist() 
{ 
    // The automatic name of the strain is the name of the first tube 
    // when the strain is registred the first time 
    $this->systematicName = $this->getTubes()->first()->getName(); 
} 
} 

回答

1

如果您需要設置prePersist事件的優先級,這可以通過使用Event Listeners and Subscribers服務,而不是做@ORM\PrePersist註釋。

首先,prePresist事件創建地鐵監聽器類:

// src/AppBundle/EventListener/TubeListener.php 
namespace AppBundle\EventListener; 

use Doctrine\ORM\Event\LifecycleEventArgs; 
use AppBundle\Entity\Tube; 

class TubeListener 
{ 
    public function prePersist(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if (!$entity instanceof Tube) { 
      return; 
     } 

     $em = $args->getEntityManager(); 
     // do something with the Tube 
    } 
} 

接下來,將註冊偵聽器,默認情況下,如果沒有則提供優先級標記屬性是zore 0

services: 
    app.event_listener.tube: 
     class: AppBundle\EventListener\TubeListener 
     tags: 
      - { name: doctrine.event_listener, event: prePersist } 

後來,創建第二個Strain監聽器類爲同一prePresist事件:

現在10

,註冊該偵聽器具有比TubeListener次要優先級:

services: 
    app.event_listener.strain: 
     class: AppBundle\EventListener\StrainListener 
     tags: 
      - { name: doctrine.event_listener, event: prePersist, priority: -5 } 

因此確保第一prePersist事件(帶有優先0)已被第二(優先-5)之前執行。這可以使用訂閱者來存檔,而不是。

+0

很抱歉這麼晚回答。我剛剛嘗試過,但我有一個空白頁面。我明白你想要做什麼。但是在這裏,我需要將我的prePersist代碼放在此頁面中,而不是放在實體中?我從來沒有用過它,對不起。 – mpiot

+1

沒關係,我需要刪除應變中的@ORM \ PrePersist,並將其保存在Tube中。然後我在Strain PrePersist上使用EventListener,然後對Tubes做一個foreach,並在我稱之爲生成應變名稱的函數之後堅持。 – mpiot