尝试保存其他实体时 Doctrine 事件侦听器中的无限循环

2024-03-30

我希望每次新的时候Distance保存实体(从 Place_A 到 Place_B),反向距离(从 Place_B 到 Place_A)也被插入到数据库中 https://stackoverflow.com/q/30569463/2516943.

我的问题是以下侦听器无限循环(因此是计数器):

class Listener
{
    public $count;

    public function prePersist(LifecycleEventArgs $eventArgs)
    {
        if ($this->count > 5) {
            die();
        }

        $entity = $eventArgs->getEntity();

        if ($entity instanceof Distance) {
            // $this->created = microtime(true) in Distance's constructor
            echo 'Entity created at ' . $entity->created;

            if ($entity->isReverse) {
                echo " is reverse\n";
            } else {
                echo " is not reverse\n";
                $this->count++;

                $reverse = new Distance();
                $reverse->setOrigin($entity->getDestination());
                $reverse->setDestination($entity->getOrigin());
                $reverse->set($entity->getMiles());
                $reverse->isReverse = true;

                $em = $eventArgs->getEntityManager();
                $em->persist($reverse);
                $em->flush();
            }
        }
    }
}

Output:

Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9073 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9078 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.908 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9084 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9087 is reverse
Entity created at 1433168310.8787 is not reverse

就像原始实体(创建时间以 8787 结尾)被保留了无数次。

以防万一,如果我删除对$em->flush,我正确地得到以下输出:

Entity created at 1433167824.2552 is not reverse
Entity created at 1433167824.2947 is reverse

但随后出现异常,表示没有参数绑定到插入查询。 Symfony 的分析器证实了这一点:

INSERT INTO Distance (
    miles, origin_id, destination_id
) 
VALUES 
(?, ?, ?)
Parameters: { }

我想了解为什么我的侦听器不能按我的预期工作,以及如何修复它。


根据要求,这里有更多代码。一切都源于一个Place除了输入地名之外,我还可以添加/删除/编辑到其他地方的距离集合Places.

// PlaceController::updateAction
public function updateAction(Request $request, $id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('MyBundle:Place')->find($id);
    if (! $entity) {
        throw $this->createNotFoundException('Unable to find Place entity.');
    }

    $deleteForm = $this->createDeleteForm($id);
    $editForm = $this->createForm(new PlaceType(), $entity, array(
        'action' => $this->generateUrl('update_place', array('id' => $entity->getId())),
        'method' => 'PUT'
    ));
    $editForm->add('submit', 'submit', array('label' => 'panel.button.save'));

    $editForm->handleRequest($request);

    if ($editForm->isValid()) {
        $em->flush();

    return array(
        'entity' => $entity,
        'form' => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    );
}

// PlaceType::buildForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $Place = $builder->getData();

    $builder
        ->add(
            'name',
            'text',
            [
                'label' => 'object.place.name'
            ]
        )
        ->add(
            'distancesTo',
            'collection',
            [
                'label' => 'object.place.distance.plural',
                'type' => new DistanceType(),
                'by_reference' => false,
                'allow_add' => true,
                'allow_delete' => true,
                'options' => [
                    'required' => false,
                    'origin' => $Place->getId() ? $Place : null
                ]
            ]
        );
}

你不应该在 prePersist 中使用 $em->flush() ,它受到 Doctrine 的限制:http://doctrine-orm.readthedocs.org/en/latest/reference/events.html#reference-events-implementing-listeners http://doctrine-orm.readthedocs.org/en/latest/reference/events.html#reference-events-implementing-listeners

有关于 preUpdate 的信息,但相同的情况(循环)适用于 prePesist 调用

9.6.6。更新前

PreUpdate 是最受限制的使用事件,因为它被称为 就在为实体内部调用更新语句之前 EntityManager#flush() 方法。 在此>事件中永远不允许更改已更新实体的关联,因为 Doctrine 无法保证在刷新操作的此时正确处理引用完整性。

这里描述了类似的情况preUpdate() 兄弟姐妹管理到树中:如何中断 ->persist() 递归? https://stackoverflow.com/questions/30240230/preupdate-siblings-manage-into-tree-how-to-break-persist-recursion/30248488?noredirect=1#comment48612464_30248488

因此,您也可以采用类似的方式:创建自定义事件,创建自定义事件订阅者,您将在其中创建反向实体并在控制器操作处分派该事件订阅者。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试保存其他实体时 Doctrine 事件侦听器中的无限循环 的相关文章

  • 如何使用CSS将背景图像放入选择选项标签中

    我有一个从 json 响应接收的国家 地区下拉列表 并且想要在国家 地区名称旁边添加相应的国家 地区国旗图标 也从 json 响应获取图像 我已经尝试了不同的 jQuery 和 bootstrap 插件 但他们所做的是破坏我以前的选择框样式
  • 按通用值对值进行分组:userid 和 ipaddress

    我正在解决数据库中的一个问题 我正在尝试查找使用多个帐户的用户 我有一个用户 ID 和使用的 IP 地址的列表 如下所示 用户 ID IP 地址 1 IP 地址 13 2 IP 地址 23 1 IP 地址 12 4 IP地址56 9 IP
  • PHP - Filter_var 替代方案?

    我构建了一个 php 脚本来输出以表单形式发布的数据 但遇到了问题 网站将运行的服务器运行 PHP 5 1 6 此版本的 PHP 不支持 filter var 我需要知道短期内的替代方案 最好是昨天 但在 Google 或 Stack Ov
  • 为什么我不能在 TCPDF 表中使用 č,ć,đ 图表?

    我正在为我的网站构建一个 tcpdf 文件 该 tcpdf 文件中有一个包含一些数据的表格 但我无法使该章程正常工作 对于编码 我使用 windows 1250 宪章女巫不起作用 我已经尝试过 utf 8 但仍然没有得到这个章程 tcpdf
  • 没有运算符与给定名称和参数类型匹配。您可能需要添加显式类型转换。 -- Netbeans、Postgresql 8.4 和 Glassfish

    我正在尝试使用 EclipseLink 在 Glassfish 中使用 JPA 编辑 Postgresql 中的表 当我插入一个实体时 它运行良好 但是 当我尝试编辑或删除同一实体时 它失败并出现以下错误 任何想法 Caused by Ex
  • PHP - 获取base64图像字符串解码并保存为jpg(生成空图像)

    嗨 我实际上是通过 ajax 发送一个 base64 图像字符串到一个 php 脚本 该脚本只是解码字符串并将内容保存为 jpg 文件 但结果是一张空图像 这怎么可能 PHP脚本 uploadedPhotos array photo 1 p
  • 从 octobercms 中的非 ajax 表单获取输入值

    我正在尝试构建一个简单的搜索功能 下面是我的搜索表格
  • 更改 WhiteOctober TCPDF 捆绑包配置值

    我已经开始在我的 symfony 项目中使用 WhiteOctober TCPDF 包 但我不知道如何更改默认配置值 例如页面格式 我尝试将其放入我的 config yml 中 white october tcpdf tcpdf k tcp
  • PHP 开发相当于 Mongrel/Webrick 吗?

    PHP 开发中是否有与 Rails 开发期间使用 Mongrel Webrick 等效的方法 我通常在端口 3000 上使用 Mongrel 在开发过程中为我的 Rails 应用程序提供服务 我从事 PHP 开发已经有几年了 据我所知 方法
  • 自定义 Facebook FOSFacebookBundle 登录按钮

    有人知道如何自定义 更改 FosFacebook 登录按钮的图像吗 facebook login button autologoutlink true 并在整页 Facebook 登录上重定向 而不是在弹出窗口上重定向 这使用了 twig
  • 阻止注销页面后的后退按钮

    我有 php 注销页面 当用户单击注销链接时 请参阅此页面并重定向到索引页面 但是当单击后退按钮时 我会看到带有用户数据的上一页 当然 当我刷新页面时 我看不到以前的页面和数据 我在单击注销并单击后退按钮后检查了其他代码 drupal 但我
  • 如何在类似 MVC 的页面中加载基于漂亮 URL 的类?

    我想请教一些关于如何解决这个问题的提示 我正在尝试构建自己的 MVC 网站 我了解了 URL 的基础知识 http example com blog cosplay cosplayer expo today 博客 gt 控制器cosplay
  • 在 Symfony 序列化中更改序列化属性名称

    我正在使用 Symfony 序列化器 效果很好 use Symfony Component Serializer Annotation Groups Groups default notification public function g
  • 强制 Composer 下载 git repo 而不是 zip

    我对作曲家有一些问题 require php gt 5 3 2 kriswallsmith buzz 0 7 Repo https github com kriswallsmith Buzz tree v0 7 https github c
  • MVC 模式中的验证层

    验证模型将使用的数据的最佳位置在哪里 例如 考虑登记表 我们有一些来自注册表的数据 那么验证这些数据的最佳位置在哪里 我们应该通过 if 语句或特殊的验证器类来检查每个数据 这意味着大量的编码 所以我想了解在哪里可以做到这一点 在控制器中
  • 从支付网关重定向回时用户会话丢失

    我已将 Cyber source 配置为我的支付网关 我能够导航到 cybersource 并进行付款 并能够成功重定向回该网站 我也可以取消付款并重定向回我的网站 我收到来自支付网关的响应 但是 用户在从支付网关重定向回来时会被注销 我正
  • 如何在 Zend Framework 3 中注册自定义表单视图助手

    我正在将继承的 Zend Framework 2 应用程序迁移到 Zend Framework 3 并且在注册自定义表单视图助手时遇到了一些困难 这些助手在应用程序使用版本 2 时起作用 主要用于添加标签属性以实现可访问性 例如 这是一个自
  • 从 PHP 数组生成 HTML 表

    我不明白这一点 我需要解决看似简单的问题 但这超出了我的逻辑 我需要编写一个函数 table columns input cols 它将输出一个表 示例 input array apple orange monkey potato chee
  • 如何从父类中获取子类名

    我试图在不需要子类上的函数的情况下完成此任务 这可能吗 我有一种感觉 但我真的很想确定
  • Laravel $request->file() 返回 null

    尝试在后端使用 Laravel 上传文件时遇到问题 Issue Laravel request gt file 方法返回 null Setup 我使用以下方法构建了一个 AJAX 请求超级代理人 https github com visio

随机推荐