Symfony2:PrePersist / PreUpdate生命周期事件未触发

时间:2012-03-13 19:42:21

标签: events symfony doctrine-orm entity

两个实体 GalleryAlbum GalleryImage 具有OneToMany / ManyToOne关系:

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

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

(以下资料)

有什么问题?

  1. 将文件添加(上传)到GalleryAlbum

  2. $ EM->坚持($相册)

  3. $ EM->齐平()

  4. 对于每个上传的文件,GalleryAlbum类创建并向$ images添加新的GalleryImage实体

  5. 我的ECHO / EXIT测试未显示(未触发GalleryImage的名为preUpload的prePersist / preUpdate事件回调函数!)

  6. 我的新图片未保存到数据库中?为什么呢?

  7. 奇怪的是什么! 如果我这样做:

    1. 添加(上传)文件

    2. $ EM->坚持($相册)

    3. $ EM->齐平()

    4. 再次$ em​​-> flush()

    5. 显示我的ECHO / EXIT测试(触发了GalleryImage的名为preUpload的prePersist / preUpdate事件回调函数!)

    6. (如果我删除echo / exit)我的新GalleryImages现在已保存!!!

    7. 为什么吗

      为什么在flush()一次时从不触发preUpload,而在flush()两次时触发preUpload?

      #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;
              }
          }
      

1 个答案:

答案 0 :(得分:6)

第一次调用persist doctrine只会保存$ album而不是其图像。您必须通过在$ images声明中指定它来指定您希望doctrine级联持久化:

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

这样当你调用persist($ album)时,它也会保留你的图像,并且应该在你的GalleryImage中触发preUpload。有一些不同的选项可用于级联,这里有很好的解释:

Doctrine transitive persistence cascade operations