我有一个 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;
}
}
现在在 CaseType
的 buildForm
方法中注册一个 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/