php - 在 Doctrine flush 中插入前删除

标签 php mysql symfony doctrine-orm

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

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

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

现在的问题是,如果我在数据库中已经有一个 Case 的 Floors,当我在我的表单中删除 Floor 并再次添加它时,它将被视为一个新的 INSERT,但是由于 Doctrine 通过执行刷新INSERTs first and DELETEs last,我会因为违反我设置的 uniqueConstraint 而得到下面的错误:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4-2' for key 'floors_case_floor_type_unique'

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

有什么方法可以让 doctrine 在 INSERT 之前执行 DELETE,或者有什么其他方法可以解决这个问题吗?

最佳答案

执行此操作的一种方法是 FormEvent .
我建议你register your FormType as a service所以你可以注入(inject)学说:

# 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();
});

关于php - 在 Doctrine flush 中插入前删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22250540/

相关文章:

security - Symfony2 in_memory 用户提供程序问题

symfony - 如何对findAll Doctrine的方法进行排序?

php - 在mysql中使用列名作为POINT几何的参数

PHP/MySQL : Database class and dependency injection

php文件不输出结果

mysql - 从 mysql 表中删除超过 100,000 行 - 服务器崩溃

php - Symfony 4 打印所有路线

php - Jeditable 不处理 id

php - sql插入查询

php - 内部加入 datamapper codeigniter