是否可以在 postPersist 中冲洗?

Oll*_*etz 4 doctrine symfony doctrine-orm

我已经阅读了关于生命周期事件的文档,以及关于在生命周期事件期间更改或持久化新实体的几个问题。打电话EnitityManager::flush()好像有问题。

好的,但是仔细查看 docs,有一个代码示例,其中在 postPersist 中更改了字段,但没有调用刷新。

我检查了一下,建议的更改没有写入数据库。只有被持久化的对象才会收到更改。

<?php

/** @Entity @HasLifecycleCallbacks */
class User
{
    // ...

    /**
     * @Column(type="string", length=255)
     */
    public $value;


    /** @PostPersist */
    public function doStuffOnPostPersist()
    {
        $this->value = 'changed from postPersist callback!';
    }
}
Run Code Online (Sandbox Code Playgroud)

也许应该将其添加到文档中。一开始我被误导了。

但是,当添加 LifecyleEventArgs 参数并刷新包含的 EntityManager 时,它们将写入 DB:

/** @PostPersist */
public function doStuffOnPostPersist(LifecycleEventArgs $args)
{
    $this->value = 'changed from postPersist callback!';
    $args->getEntityManager()->flush(); // works in my tests. Is this safe to use ?

}
Run Code Online (Sandbox Code Playgroud)

我不知道如何解释有关flush在 postPersist 内部调用是否可以的文档

如您所见,我正在寻找一种可靠的方法在插入或更新实体后对它们执行某种后处理。我必须使用 postPersist,因为我需要自动生成的主键值。

附带问题:如果是,可以刷新,那么我还可以在 PostUpdate 中保留其他对象吗?像这样:

 /** @PostPersist */
public function doStuffOnPostPersist(LifecycleEventArgs $args)
{
    $this->value = 'changed from postPersist callback!';
    $obj = new OtherObject("value " . $this->value);
    $args->getEntityManager()->persist($obj);
    $args->getEntityManager()->flush(); // works in my tests. Is this safe to use ?

}
Run Code Online (Sandbox Code Playgroud)

侧面问题:我尝试了最后一个变体,它似乎有效。但它是有效的,还是我可能会创建深度递归堆栈?根据该文档时,postPersist代码被称为冲洗,所以如果我postPersist期间调用flush,我必须要小心,不要坚持执行相同的处理程序,这将导致无穷递归的对象。这样对吗?

iii*_*rxs 5

我检查了一下,建议的更改没有写入数据库。只有被持久化的对象才会收到更改。

也许应该将其添加到文档中。一开始我被误导了。

文档中的代码不会尝试在数据库中保留对 value 属性的这种修改,这flush()就是调用no 的原因。这只是一个例子,这个值也可以是一个未映射到 class 的数据库属性的值User

我不知道如何解释有关在 postPersist 中调用flush是否可以的文档。

可以调用flush()PostPersist 生命周期回调来更改实体的映射属性。在您的 PostPersist 回调中,您的实体已经插入到您的数据库中。通过更改属性值并调用flush()您的实体将被标记为要更新,因此不会再次调度 PostPersist 事件(而是调度 Pre/PostUpdate 事件)。

附带问题:如果是,可以刷新,那么我还可以在 PostUpdate 中保留其他对象吗?

在 PostPersist 事件回调中持久化另一个实体类的新对象也没有问题,但是如果你尝试在这个 PostPersist 回调中持久化同一个(用户)类的对象,你将有无限递归,因为你可以很容易地理解。

侧面问题:我尝试了最后一个变体,它似乎有效。但它是有效的,还是我可能会创建深度递归堆栈?

正如我之前所解释的,如果不持久化回调所属的同一类(用户)的对象,则此代码不会创建太深的递归堆栈或无限循环。该flush()会只调用两次。尽管在还必须处理关联时事情会变得更加复杂,但在您的示例中没有这样的问题。