Symfony2: PrePersist / PreUpdate event does not fire

The two GalleryAlbum and GalleryImage objects are related to OneToMany / ManyToOne:

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

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

(sources below)

What is the problem?

  • Adding (uploading) files to GalleryAlbum

  • $ em-> saved ($ album)

  • $ em-> flush ()

  • For each uploaded file, the GalleryAlbum class creates and adds a new GalleryImage to $ images

  • My ECHO / EXIT test is not displayed (GalleryImage prePersist / preUpdate callback function with the name preUpload does not start!)

  • My new images are not saved in the database? Why?

What a strange thing! If I do this:

  • Adding (uploading) files

  • $ em-> saved ($ album)

  • $ em-> flush ()

  • again $ em-> flush ()

  • My ECHO / EXIT test is shown (the Capture function is initiated).

  • (if I delete echo / exit) My new GalleryImages are now saved !!!

Why?

Why does preUpload never start on a single reset () and fire when I double-clean ()?

# 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 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 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
source share
1 answer

The first call to persist doctrine will save only the $ album, not its image. You must indicate that you want the doctrine to cascade persist by specifying it in the $ images declaration:

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

Thus, when you call persist ($ album), it will also be saved on your images and should run preUpload in your GalleryImage. Several different options are available for cascading, and here they are well explained:

Cascading transitive resilience Doctrine

+6
source

Source: https://habr.com/ru/post/910629/


All Articles