是否可以在 postPersist 中刷新? [英] Flushing in postPersist possible or not?

查看:20
本文介绍了是否可以在 postPersist 中刷新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读有关生命周期事件的文档,以及关于 SO 在生命周期事件期间更改或保留新实体的几个问题.调用 EntityManager::flush() 似乎有问题.

I have read the docs about lifecycle events, and several questions here on SO about changing or persisting new entities during lifecycle events. Calling EnitityManager::flush() seems to be a problem.

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

Ok, but looking carefully at the docs, there is a code example where the field is changed in postPersist, but no flush is called.

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

I checked that, and the suggested change is not written to the DB. Only the object being persisted does receive the change.

<?php

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

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


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

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

Maybe one should add this to the docs. I was mislead at first.

然而,当添加 LifecyleEventArgs 参数并刷新包含的 EntityManager 时,它们会被写入 DB:

However, when adding the LifecyleEventArgs argument and flushing the contained EntityManager, they are written to 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 ?

}

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

I don't know how to interpret the docs about whether it is OK or not to call flush inside the postPersist.

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

As you can see, I am searching for a reliable way to perform some kind of postprocessing to my entities after inserting or updating them. I have to use postPersist, since I need the auto-generated primary key value.

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

Side question: If yes, it is ok to flush, could I then also persist other objects in PostUpdate? Like so:

 /** @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 ?

}

侧面问题:我已经尝试了最后一个变体,它似乎有效.但它是否有效,或者我是否可能创建深度递归堆栈?根据文档,在刷新期间调用 postPersist 代码,所以如果我在 postPersist 期间调用刷新,我必须小心不要持久化执行相同处理程序的对象,这会导致无限递归.这是正确的吗?

Side-side question: I have tried the last variant, and it seems to work. But is it efficient, or am I possibly creating deep recursion stacks? According to the docs, the postPersist code is called during flush, so if I call flush during postPersist, I have to be careful not to persist an object that executes the same handler, which would lead to infinite recursion. Is this correct?

推荐答案

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

I checked that, and the suggested change is not written to the DB. Only the object being persisted does receive the change.

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

Maybe one should add this to the docs. I was mislead at first.

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

The code in the docs doesn't try to persist this modification of the value property in database that's why no flush() is called. It's just show an example and this value could also be an unmapped to the database property of class User.

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

I don't know how to interpret the docs about whether it is OK or not to call flush inside the postPersist.

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

It is ok to call flush() on a PostPersist lifecycle callback in order to change a mapped property of your entity. In your PostPersist callback your entity has already been inserted in your database. By changing the property value and calling flush() your entity will be flag as to be updated, so the PostPersist event won't be dispatched again (instead Pre/PostUpdate events will be dispatched).

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

Side question: If yes, it is ok to flush, could I then also persist other objects in PostUpdate?

在 PostPersist 事件回调中持久化另一个实体类的新对象也没有问题,但是如果您尝试在此 PostPersist 回调中保留相同(用户)类的对象,您将拥有一个无限递归,你很容易理解.

It is also ok to persist an new object of another entity class in a PostPersist event callback with no problem, but if you try to persist an object of the same (User) class in this PostPersist callback you will have an infinite recursion, as you can easily understand.

附带问题:我已经尝试了最后一个变体,它似乎有效.但它是否有效,或者我可能会创建深度递归堆栈?

Side-side question: I have tried the last variant, and it seems to work. But is it efficient, or am I possibly creating deep recursion stacks?

正如我之前解释的那样,如果不持久化回调所属的同一类(用户)的对象,则此代码不会创建太深的递归堆栈或无限循环.flush() 将被调用两次.虽然在处理关联时事情可能会变得更加复杂,但在您的示例中不存在这样的问题.

As I have explained before this code doesn't create too deep recursion stacks or infinite loops if not persisting objects of the same class (User) in which the callback belongs. The flush() will be called exactly two times. Although things could get more complicated when having also to deal with associations, in your example there is not such problem.

这篇关于是否可以在 postPersist 中刷新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆