我有这个结构:
Root Level
-- Level 1 id : 1100 --> trying to delete this level
---- Level 1.1 id : 1101
------ product 1
------ product 2
我想删除级别1,级联删除级别1.1及其2个子级。
当我这样做时,我违反了完整性约束:
$em->remove($level);
$em->flush();
$level
代表等级1 。
使用params [1100]
执行DELETE FROM level WHERE id = ?
时发生异常无法删除或更新父行:外键约束失败(mydb.product,CONSTRAINT my_constraint FOREIGN KEY(Level_ID)REFERENCES level(id))
此错误似乎出现在"产品"表
我的实体:
class Level
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @Gedmo\TreeParent
* @ORM\ManyToOne(targetEntity="Level", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity="Level", mappedBy="parent")
* @ORM\OrderBy({"lft" = "ASC"})
*/
private $children;
/**
* @ORM\OneToMany(targetEntity="Product", mappedBy="level", cascade={"persist", "remove"})
* @ORM\OrderBy({"order" = "ASC"})
* @Assert\Valid
*/
private $products;
}
此实体是根据Tree extension for Doctrine2
构建的A Level可以拥有父级(同一实体)。
A Level可以有一个或多个产品。
class Product
{
/**
* @ORM\Column(name="Product_Code", type="string", length=20)
* @ORM\Id
*/
private $code;
/**
* @ORM\Column(name="Level_ID", type="integer")
* @ORM\Id
*/
private $levelId;
/**
* @ORM\ManyToOne(targetEntity="Level", inversedBy="products")
* @ORM\JoinColumn(name="Level_ID", referencedColumnName="id")
*/
private $level;
}
我不太清楚问题出在哪里。通常,应首先删除产品,然后删除1.1级和1级。
1级没有产品但是,它可能会尝试删除level_id = 1100
(而不是1101)的产品?
如果没有产品,删除效果很好。当我删除具有子级别的级别时,会正确删除所有级别。
cascade={"persist", "remove"}
似乎不适用于我的产品系列(在Level实体中)。
这很奇怪,因为我在数组集合等中使用了很多实体和关系,之前我没有遇到过这个错误。
感谢您的帮助。
修改
我找到了一个解决方案,但我认为这不是正确的方法。我必须在控制器中手动执行级联删除:
/* browse children levels */
foreach ($level->getChildren() as $child) {
/* browse the products within the child level */
foreach ($child->getProducts() as $product) {
$em->remove($product); -- delete product
}
}
$em->remove($level); -- delete the level (delete also children levels)
$em->flush(); -- update database