2012-03-13 59 views
6

兩個實體GalleryAlbumGalleryImage具有一對多/多對一關係:Symfony2中:PrePersist /更新前的生命週期事件不會激發

One GalleryAlbum ==== can have ====> Many GalleryImage

Many GalleryImage === can be in ===> One GalleryAlbum

(下面源)

是什麼問題?

  1. 添加(上載)文件GalleryAlbum

  2. $ EM->堅持($專輯)

  3. $ EM->的flush()

  4. 對於每個上傳的文件GalleryAlbum類創建並添加到$圖像一個新的GalleryImage實體

  5. 我的ECHO/EXIT測試是否(GalleryImage的prePersist/preUpdate事件回調函數名爲preUpload不會被觸發!)

  6. 我的新圖像沒有保存到數據庫?爲什麼?

有什麼奇怪的!如果我做的:

  1. 添加(上載)文件

  2. $ EM->堅持($專輯)

  3. $ EM->的flush()

  4. again $ em-> flush()

  5. 我的ECHO/EXIT測試顯示(GalleryImage的名爲preUpload的prePersist/preUpdate事件回調函數被觸發!)

  6. (如果我刪除回顯/退出)我的新GalleryImage保存了!

爲什麼?

爲什麼preUpload從不觸發當我flush()一次,並且當我flush()兩次時被觸發?

#SRC GalleryAlbum.php

 
    /** 
    * @ORM\Entity 
    * @ORM\HasLifecycleCallbacks 
    * @ORM\Table(name="gallery_album") 
    */ 
    class GalleryAlbum 
    { 
     // some properties like id, name, description, etc 

     /** 
     * @ORM\OneToMany(targetEntity="GalleryImage", mappedBy="parent") 
     */ 
     protected $images; 

     /* Files container. Used for upload service. Must not be persisted. */ 

     protected $files;  

     /* @ORM\Column(type="boolean", nullable=TRUE) 
     * 
     * if set to true will updateing object and calling preUpdate event callback 
     * becouse it's always set to null in database by prePersist event callback */ 

     protected $files_added; 

     /** 
     * Set container files 
     * 
     * @return GalleryAlbum 
     */ 
     public function setFiles($files) 
     { 
      $this->files = $files; 
      $this->files_added = true; 
      /* setting files_added to true forces EntityManager to update 
       * this GalleryAlbum even if no other properties have changed */ 

      return $this; 
     } 

     /** 
     * @ORM\PrePersist() 
     * @ORM\PreUpdate() 
     */ 
     public function preUpload() 
     { 
      if(null !== $this->files) { 
       foreach($this->files as $key =>$file) { 
        $this->addGalleryElement($file); 
        unset($this->files[$key]); 
       } 
      } 
      /* Resetting property files_added to NULL 
      * so it always stays null in database */ 
      $this->files_added = null; 
     } 


     /** 
     * Constructing new GalleryImage and setting it's file and parent 
     */ 
     public function addGalleryElement($file) 
     {  
      $element = new GalleryImage($this, $file); 
      $this->addGalleryImage($element); 
     } 
    } 

#SRC GalleryImage。PHP

 
    /** 
    * @ORM\Entity 
    * @ORM\HasLifecycleCallbacks 
    * @ORM\Table(name="gallery_image") 
    */ 
    class GalleryImage 
    { 
     // some properties like id, name, description, etc 

     /** 
     * @ORM\ManyToOne(targetEntity="GalleryAlbum", inversedBy="images") 
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id") 
     */ 
     protected $parent; 

     /* Constructing new GalleryImage */ 

     public function __construct($parent = null, $file = null) 
     { 
      if($parent) $this->setParent($parent); 
      if($file) $this->setFile($file);  
     } 

     /** 
     * @ORM\PrePersist() 
     * @ORM\PreUpdate() 
     */ 
     public function preUpload() 
     { 
      echo 'TEST: is this event callback function fired?'; exit; 

      if(null !== $this->file) { 
       $this->path = $this->file->guessExtension(); 
      } 

      $this->file_added = null; 
     } 
    } 

回答

6

第一次調用堅持教條只會節省$專輯,而不是它的圖像。您必須指定要學說級聯由$圖像聲明,指明它的堅持:

/** 
    * @ORM\OneToMany(targetEntity="GalleryImage", mappedBy="parent", cascade={"persist", "remove"}) 
    */ 
    protected $images; 

這樣,當你調用堅持($專輯)也將繼續存在你的圖片,應該在你的GalleryImage觸發preUpload 。有許多可用於級聯一些不同的選擇和他們很好這裏解釋:

Doctrine transitive persistence cascade operations

+0

不幸加入級聯= {「堅持」,「刪除」},甚至級聯= {「所有」}並不能改變什麼:( – loostro 2012-03-13 22:24:51

+0

這很奇怪,前幾天我遇到了同樣的問題,這個問題給我解決了,如果我想到別的什麼,我會回來 – user1207727 2012-03-13 23:17:23

+0

好的,我知道爲什麼雙重刷新工作,我在「prePersist 「這意味着教義ORM已經計算出哪些實體需要被持久化,因此,當第一次調用flush時 - 只有ALBUM被持久化,當調用它時,第二次教義看到新實體被持久化,這就是爲什麼它將它們保存到數據庫在第二次沖洗之後。 – loostro 2012-03-14 12:40:01

相關問題