我需要一些帮助来理解cascade
如何与Symfony2实体关联一起使用,特别是“删除”选项。因为当我尝试删除实体时,存在数据库外键冲突,它不会从数据库中删除。
我有两个测试实体:
/**
* @ORM\Entity
* @ORM\Table(name="test")
*/
class Test extends Entity\Base {
/**
* This is a OneToOne Unidirectional association, just so that we can get the
* current published version easily, based on the publishedId.
* @ORM\OneToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\TestVersion")
* @ORM\JoinColumn(name="publishedId", referencedColumnName="id")
*/
protected $published;
/**
* @ORM\Column(type="integer", nullable=true)
*/
protected $publishedId = NULL;
/**
* This is the regular OneToMany Bi-Directional Association, for all the versions.
* @ORM\OneToMany(targetEntity="\Gutensite\CmsBundle\Entity\View\TestVersion", mappedBy="view", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $versions;
}
/**
* @ORM\Entity
* @ORM\Table(name="test_version")
*/
class TestVersion extends Entity\Base {
/**
* @ORM\ManyToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\Test", inversedBy="versions")
* @ORM\JoinColumn(name="viewId", referencedColumnName="id")
*/
protected $view;
/**
* The primary view entity that this version belongs to.
* @ORM\Column(type="integer", nullable=true)
*/
protected $viewId;
}
*注意:我最初的双向OneToOne关系有cascade = {“persist”,“remove”},但意识到这是不需要的。无论哪种方式,问题都完全相同。
在控制器中,我创建了一个这样的测试实体:
$view = new Test();
$version = new TestVersion();
// associate the version with the view
$view->addVersion($version);
// mark this version as the published version (this is where the problem happens, though)
$view->setPublished($version);
$em->persist($view);
$em->flush();
这会在test_version中为test和一个关联版本创建一条主记录:
|---------------------|
| table: test |
|---------------------|
| id | publishedId |
| 100 | 500 |
|---------------------|
|---------------------|
| table: test_version |
|---------------------|
| id | viewId |
| 500 | 100 |
|---------------------|
*注意:test_version.viewId是通过我的test.addVersion()方法手动设置的,该方法调用$ version-> setView($ this)。
但是当我去测试时删除主要实体时:
$view = $em->getRepository("GutensiteCmsBundle:View\Test")->find($request->query->get('id'));
$em->remove($view);
$em->flush();
它尝试删除主测试实体但失败,因为它被test_version.viewId引用。
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`cms`.`test_version`, CONSTRAINT `FK_635D070BCEB972AA` FOREIGN KEY (`viewId`) REFERENCES `test` (`id`))
如果我手动尝试删除数据库中的test_version记录,它也会因类似错误而失败:
ERROR 1451: 1451: Cannot delete or update a parent row: a foreign key constraint fails (`cms`.`test`, CONSTRAINT `FK_D87F7E0C628CCE00` FOREIGN KEY (`publishedId`) REFERENCES `test_version` (`id`)) SQL Statement: DELETE FROM `cms`.`test_version` WHERE `id`='17'
Soooooo .....如果cascade = {“remove”}实际上没有删除相关实体(或者那个实体的父实体),有什么意义? < / p>
我可以删除这些记录的唯一方法是,如果我取消设置$ view-&gt; publishId,它会破坏外键关联重叠。
$view = $em->getRepository("GutensiteCmsBundle:View\Test")->find($request->query->get('id'));
$view->setPublishedId(NULL);
$em->persist($view);
$em->flush();
$em->remove($view);
$em->flush();
显然这是由于OneToOne和OneToMany关联之间的重叠造成的。在删除视图之前,我可以忍受在unsetting publishedId的必要性。但我希望专家的反馈能够知道这是否有问题。或建议为这些协会提供更好的解决方案。但是,我有其他记录(如多个路由)指向单个视图实体,因此这就是为什么版本在他们自己的实体上(也是为了保持大量数据在另一个表中进行优化)。所以我的模型似乎很合乎逻辑,例如我想要一个快速简单的方法来引用已发布的版本。我认为单向关系不会造成问题。但它确实......