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

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

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

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

(以下来源)

有什么问题?

  1. 向 GalleryAlbum 添加(上传)文件

  2. $em->persist($album)

  3. $em->flush()

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

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

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

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

  1. 添加(上传)文件

  2. $em->persist($album)

  3. $em->flush()

  4. 再次 $em->flush()

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

  6. (如果我删除 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; } }

【问题讨论】:

    标签: events symfony doctrine-orm entity


    【解决方案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”解决了我的问题(因此,每当我的相册实体上传了一些文件 - 它都会为它们创建实体)。
    • 酷。我很高兴你最终找到了它的底部
    猜你喜欢
    • 2011-11-10
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多