due entità GalleryAlbum e GalleryImage avere OneToMany/ManyToOne relazione:Symfony2: PrePersist/PreUpdate ciclo di vita-evento non ha sparato
One GalleryAlbum ==== can have ====> Many GalleryImage
Many GalleryImage === can be in ===> One GalleryAlbum
(fonti sotto)
Qual è il problema?
Aggiunta di file (upload) a GalleryAlbum
$ em-> persist ($ album)
$ em-> a filo()
Per ogni file caricato La classe GalleryAlbum crea e aggiunge a $ images una nuova entità GalleryImage
Il mio test ECHO/EXIT è no t mostrato (la funzione di callback dell'evento prePersist/preUpdate di GalleryImage denominata preUpload non viene attivata!)
Le mie nuove immagini non vengono salvate nel database? Perché?
Che cosa è strano!Se faccio:
Aggiunta (upload) file
$ em-> persist ($ album)
$ em-> flush()
again $ em-> flush()
Il mio test ECHO/EXIT è mostrato (la funzione di callback prePersist/preUpdate dell'evento denominata preUpload è attivata!)
(se cancello echo/exit) Le mie nuove GalleryImages vengono salvate ora !!!
Perché?
Perché preUpload non viene mai attivato quando si scarica() una volta e viene attivato quando si esegue il flush() due volte?
# 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; } }
purtroppo aggiungendo cascade = { "persistere", "rimuovere"} o anche cascade = { "tutti"} non cambia nulla :( – loostro
Questo è strano, ho avuto lo stesso problema qualche giorno fa e questo ha risolto il problema per me.Tornerò se penso a qualsiasi altra cosa – user1207727
OK so perché il doppio flush funziona. Sto creando nuove Entità in "prePersist" "Ciò significa che la dottrina ORM ha già calcolato quali entità devono essere persistenti, quindi quando si chiama flush per la prima volta - viene mantenuto solo ALBUM. Quando lo si chiama la seconda volta la dottrina vede persistere le nuove entità e questo è il motivo per cui le salva in database dopo 2nd flush. – loostro