【问题标题】:Delete Before Insert in Doctrine flush在 Doctrine 刷新中插入之前删除
【发布时间】:2014-04-10 15:02:42
【问题描述】:

我有一个可以有多个楼层 (OneToMany) 的案例实体,每个楼层都有一个指定其类型的 FloorType。我的 Floors 实体上也有一个 UniqueConstraint,它不允许每个 Case 有两个 FloorType 相同的 Floors。

为了在每个案例中插入楼层,我为楼层创建了一个 Symfony 集合类型,并使用 js 将新楼层添加到我的案例中。

Symfony 的表单集合文档说,如果一个项目没有提交,它会自动从数据库中删除。

现在的问题是,如果我已经在 DB 中有一个案例的楼层,当我在我的表单中删除楼层并再次添加它时,它将被视为一个新的插入,但由于 Doctrine 通过执行刷新首先插入,最后删除,我会因为违反我设置的 uniqueConstraint 而收到以下错误:

SQLSTATE[23000]:违反完整性约束:1062 键“floors_case_floor_type_unique”的重复条目“4-2”

这意味着 Doctrine 试图在 Floors 表中插入一行,其 FloorType 与已删除的行相同,然后再尝试从同一个表中删除最后一行。

有没有什么方法可以让教义在INSERT之前做DELETE,或者有什么其他的方法来解决这个问题?

【问题讨论】:

    标签: php mysql symfony doctrine-orm


    【解决方案1】:

    一种方法是FormEvent
    我建议你register your FormType as a service 这样你就可以注入教义

    # in your services.yml:
    services:
        yourbundle.form.case_type:
            class: Your\Bundle\CaseType
            arguments: ["@doctrine"]
            tags:
                - { name: form.type, alias: your_bundle_case_type }
    

    并扩展您的 FormType

    class CaseType /*...*/
    {
        private $doctrine;
    
        public function __construct($doctrine)
        {
            $this->doctrine = $doctrine;
        }
    }
    

    现在在CaseTypebuildForm 方法中注册一个EventListener

    $builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
         $data = $event->getData();
         $em  = $this->doctrine->getEntityManager();
    
         foreach ($data['floor'] as $floor) {
             // delete floors here...
             $duplicateFloor = $em->find('YourBundle:Floor', $floor->getId);
             $em->remove($duplicateFloor);
         }
         $em->flush();
    });
    

    【讨论】:

    • 我尝试手动移除地板,不是在事件中,而是在表单验证后在我的控制器中。但问题是,如果我在移除地板后进行冲洗,因为 Case 已经在 Doctrine 的监视下,它会再次尝试在 DELETE 之前进行 INSERT。
    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    相关资源
    最近更新 更多