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

Posted

技术标签:

【中文标题】Symfony2:PrePersist/PreUpdate 生命周期事件未触发【英文标题】:Symfony2: PrePersist/PreUpdate lifecycle-event not fired 【发布时间】:2012-03-30 06:13:33 【问题描述】:

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

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

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

(以下来源)

有什么问题?

    向 GalleryAlbum 添加(上传)文件

    $em->persist($album)

    $em->flush()

    GalleryAlbum 类为每个上传的文件创建一个新的 GalleryImage 实体并将其添加到 $images 中

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

    我的新图像没有保存到数据库中?为什么?

有什么奇怪的! 如果我这样做:

    添加(上传)文件

    $em->persist($album)

    $em->flush()

    再次 $em->flush()

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

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

为什么?

为什么preUpload每次flush()都没有触发,flush()两次才触发?

# src GalleryAlbum.php

/** * @ORM\实体 * @ORM\HasLifecycleCallbacks * @ORM\Table(name="gallery_album") */ 相册相册类 // 一些属性,如 id、name、description 等 /** * @ORM\OneToMany(targetEntity="GalleryImage", mappedBy="parent") */ 受保护的$images/* 文件容器。用于上传服务。不得坚持。 */ 受保护的 $files; /* @ORM\Column(type="boolean", nullable=TRUE) * * 如果设置为 true 将更新对象并调用 preUpdate 事件回调 * 因为它总是通过 prePersist 事件回调在数据库中设置为 null */ 受保护的$files_added; /** * 设置容器文件 * * @return 画廊相册 */ 公共函数 setFiles($files) $this->files = $files; $this->files_added = true; /* 将 files_added 设置为 true 会强制 EntityManager 更新 * 这个 GalleryAlbum 即使没有其他属性改变 */ 返回 $this; /** * @ORM\PrePersist() * @ORM\PreUpdate() */ 公共函数 preUpload() if(null !== $this->files) foreach($this->文件为 $key => $file) $this->addGalleryElement($file); 未设置($this->文件[$key]); /* 将属性 files_added 重置为 NULL * 所以它在数据库中总是保持为空 */ $this->files_added = null; /** * 构建新的 GalleryImage 并设置它的文件和父级 */ 公共函数 addGalleryElement($file) $element = new GalleryImage($this, $file); $this->addGalleryImage($element);

# src GalleryImage.php

/** * @ORM\实体 * @ORM\HasLifecycleCallbacks * @ORM\Table(name="gallery_image") */GalleryImage // 一些属性,如 id、name、description 等 /** * @ORM\ManyToOne(targetEntity="GalleryAlbum", inversedBy="images") * @ORM\JoinColumn(name="parent_id", referencedColumnName="id") */ 受保护的 $parent; /* 构造新的 GalleryImage */ 公共函数 __construct($parent = null, $file = null) if($parent) $this->setParent($parent); if($file) $this->setFile($file); /** * @ORM\PrePersist() * @ORM\PreUpdate() */ 公共函数 preUpload() echo '测试:这个事件回调函数被触发了吗?'; 退出; if(null !== $this->file) $this->path = $this->file->guessExtension(); $this->file_added = null;

【问题讨论】:

【参考方案1】:

第一次调用 persist 原则时只会保存 $album 而不是它的图像。你必须通过在 $images 声明中指定你希望学说级联持久化:

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

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

Doctrine transitive persistence cascade operations

【讨论】:

不幸的是添加 cascade="persist", "remove" 甚至 cascade="all" 不会改变任何东西:( 这很奇怪。几天前我遇到了同样的问题,这为我解决了这个问题。如果我想到别的什么我会回来的 好的,我知道为什么双冲洗有效。我正在“prePersist”中创建新实体,这意味着 ORM 学说已经计算出哪些实体需要被持久化。因此,当第一次调用 flush 时 - 只有 ALBUM 被持久化。当第二次调用它时,学说看到新实体被持久化,这就是为什么它在第二次刷新后将它们保存到数据库中。 我通过在“setFiles”中调用“preUpload”解决了我的问题(因此,每当我的相册实体上传了一些文件 - 它都会为它们创建实体)。 酷。我很高兴你最终找到了它的底部

以上是关于Symfony2:PrePersist/PreUpdate 生命周期事件未触发的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 无法连接到 sqlite

找不到 Symfony2 组件类

Symfony2 - 访问被拒绝

Symfony2 / SonataUserBundle - 注册后自动登录

Symfony2 OneToMany 关系

Symfony2无效形式没有错误