两个实体 GalleryAlbum 和 GalleryImage 具有OneToMany / ManyToOne关系:
One GalleryAlbum ==== can have ====> Many GalleryImage
Many GalleryImage === can be in ===> One GalleryAlbum
(以下资料)
有什么问题?
将文件添加(上传)到GalleryAlbum
$ EM->坚持($相册)
$ EM->齐平()
对于每个上传的文件,GalleryAlbum类创建并向$ images添加新的GalleryImage实体
我的ECHO / EXIT测试未显示(未触发GalleryImage的名为preUpload的prePersist / preUpdate事件回调函数!)
我的新图片未保存到数据库中?为什么呢?
奇怪的是什么! 如果我这样做:
添加(上传)文件
$ EM->坚持($相册)
$ EM->齐平()
再次$ em-> flush()
显示我的ECHO / EXIT测试(触发了GalleryImage的名为preUpload的prePersist / preUpdate事件回调函数!)
(如果我删除echo / exit)我的新GalleryImages现在已保存!!!
为什么吗
为什么在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; } }
答案 0 :(得分:6)
第一次调用persist doctrine只会保存$ album而不是其图像。您必须通过在$ images声明中指定它来指定您希望doctrine级联持久化:
/**
* @ORM\OneToMany(targetEntity="GalleryImage", mappedBy="parent", cascade={"persist", "remove"})
*/
protected $images;
这样当你调用persist($ album)时,它也会保留你的图像,并且应该在你的GalleryImage中触发preUpload。有一些不同的选项可用于级联,这里有很好的解释: