学说2,需要执行代码预先持久化/后持久化

时间:2011-10-11 21:07:49

标签: persistence doctrine-orm

我正在使用Doctrine 2实体。我们有一些实体在保存到数据库时必须更新相关项目。例如,当修改用户记录时,我们将其保存为新记录,并将“inactive”字段设置为“false”。但是,我们必须将该用户以前所有记录的“非活动”字段设置为“true”。这样做是为了保留审计历史记录。它是一个Legacy数据库,因此不能选择更改结构。

由于Doctrine通过将对象传递给persister对象(persist ::($ thisObj))而不是具有save方法($thisObj->save())的对象来保存对象,因此我们不能只扩展'save'来自父对象的方法。我在这里看到的唯一选择是尝试扩展'persist'对象,但这听起来像是一个鹅群,只是等待发生。

我发现了一些关于事件的信息,但是没有看到如何添加它们以使事件在持久保存特定实体时触发特定功能。

如何为我的某些实体添加预存/保存后功能?

3 个答案:

答案 0 :(得分:12)

那么,您可能已经知道http://www.doctrine-project.org/docs/orm/2.1/en/reference/events.html了吗?

添加一个实体包含回调的注释,然后在该实体上创建特定的函数(需要公开),并使用@PrePersist或@PostPersist或其他任何内容对它们进行注释。

另一种方法是创建一个事件订阅者,使用doctrine事件管理器注册一个事件订阅者,并实现名为prePersist,postPersist等的方法。他们会传递一个EventArguments对象,该对象包含与发生的事件相关的实体。

我知道这是对你的问题的一般回答,但你需要更具体地解决问题所在。

请不要执行实体管理器并覆盖持久化方法,就我所知,有更简洁的方法可以满足您的需求。

答案 1 :(得分:7)

做你想做的事实际上很简单。它不需要与事件管理器一起使用,也不需要像这样复杂的事情。您使用称为“生命周期回调”的东西。这些是Doctrine在实体的“生命周期”中自动运行的函数,即:prePersist,postPersist,preUpdate,postUpdate等。您可以在此处找到完整列表:http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html

将此功能添加到您的实体的过程非常简单。

     
  1. 在实体的“注释”部分中,包含以下标记:“@HasLifecycleCallbacks”。这告诉Doctrine应该在实体中搜索要在各种事件上运行的函数
  2. 在您的实体中编写一个您希望触发特定事件的公共函数。
  3. 在函数上方放置一个注释,指示应该使用哪个事件来处理。
  4. 例如,请查看以下代码:

    /** @PostPersist  */
    public function doSPostPersist() {
        $this->tester = 'Value changed by post-persist';
    }
    

    我发现有时事件只是拒绝开火,我还不知道为什么。但是当它们发射时,它们会可靠地发射。

答案 2 :(得分:2)

不要忘记在类注释中启用Lifecycle Callback:

/**
 * Report\MainBundle\Entity\Serveur
 * @ORM\HasLifecycleCallbacks
 */
class Serveur {