实体之间违反完整性约束 1451

Integrity constraint violation 1451 between entities

我有这些实体(问题的相关部分):

 /**
 * Criterion
 *
 * @ORM\Table(name="innova_stepcondition_criterion")
 * @ORM\Entity(repositoryClass="Innova\PathBundle\Repository\CriterionRepository")
 */
class Criterion implements \JsonSerializable
{
    /**
     * Criteriagroup
     * @var \Innova\PathBundle\Entity\Criteriagroup
     *
     * @ORM\ManyToOne(targetEntity="Innova\PathBundle\Entity\Criteriagroup", inversedBy="criteria", cascade={"all"})
     * @ORM\JoinColumns({
     *  @ORM\JoinColumn(onDelete="SET NULL")
     * })
     */
    protected $criteriagroup;
}

/**
 * Criteriagroup
 *
 * @ORM\Table(name="innova_stepcondition_criteriagroup")
 * @ORM\Entity(repositoryClass="Innova\PathBundle\Repository\CriteriagroupRepository")
 */
class Criteriagroup implements \JsonSerializable
{
    /**
     * Criteria linked to the criteriagroup
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Innova\PathBundle\Entity\Criterion", mappedBy="criteriagroup", indexBy="id", cascade={"persist", "remove"})
     */
    protected $criteria;
}

当我尝试删除标准组时,我想删除附加的标准。我遇到了这个错误:

 An exception occurred while executing 'DELETE FROM innova_stepcondition_criteriagroup WHERE id = ?' with params [1]: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`claroline_path`.`innova_stepcondition_criteriagroup`, CONSTRAINT `FK_F33A94EA727ACA70` FOREIGN KEY (`parent_id`) REFERENCES `innova_stepcondition_criteriagroup` (`id`))

所以我读了一些 post,比如 this our this one,建议的解决方案是在 ManyToOne 端的 joinColumn 上使用 onDelete="SET NULL",我做过。但我仍然收到此错误。

有什么问题吗? 谢谢

编辑:

@RaulFerriz:谢谢你的回答。如果我尝试你的修改:在 Criterion 中使用 cascade={"persist"} 而不是 cascade={"all"},我仍然有同样的错误。

但是如果我完全删除 Criterion 中的级联,我有:

A new entity was found through the relationship \u0027Innova\PathBundle\Entity\Criterion#criteriagroup\u0027 that was not configured to cascade persist operations for entity: Innova\PathBundle\Entity\Criteriagroup@0000000034dfa7b200000000f76198d8. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={\u0022persist\u0022}). If you cannot find out which entity causes the problem implement \u0027Innova\PathBundle\Entity\Criteriagroup#__toString()\u0027 to get a clue` 

这似乎意味着需要级联={"persist"}。

我不知道接下来要尝试什么。 每次修改后我做一个doctrine:schema:update。

由于您已经定义了实体,因此当您尝试删除 "Criterion" 时,实体 Criteriongroup 也将被删除。这不是您要实现的目标。

试试这个

/** * Criterion * * @ORM\Table(name="innova_stepcondition_criterion") * @ORM\Entity(repositoryClass="Innova\PathBundle\Repository\CriterionRepository") */ class Criterion implements \JsonSerializable { /** * Criteriagroup * @var \Innova\PathBundle\Entity\Criteriagroup * * @ORM\ManyToOne(targetEntity="Innova\PathBundle\Entity\Criteriagroup", inversedBy="criteria") * @ORM\JoinColum(referencedColumnName="id") */ protected $criteriagroup; }

还有这个 /** * Criteriagroup * * @ORM\Table(name="innova_stepcondition_criteriagroup") * @ORM\Entity(repositoryClass="Innova\PathBundle\Repository\CriteriagroupRepository") */ class Criteriagroup implements \JsonSerializable { /** * Criteria linked to the criteriagroup * @var \Doctrine\Common\Collections\ArrayCollection * * @ORM\OneToMany(targetEntity="Innova\PathBundle\Entity\Criterion", mappedBy="criteriagroup", indexBy="id", cascade={"persist", "remove"}) */ protected $criteria; }

基本上,从所有级联中清除 Criterion 实体,我想你最多需要 {cascade="persist"} 在这个实体上,这意味着:当 Criterion 被持久化时,也持久化与之链接的 Criteriagroup。

您的问题不在您的关系 Criteriagroup 和 Criteria 中。

如果检查 SQL 错误,失败的约束是针对字段 parent_id。这是您的 Criteriagroup / Criteriagroup 关系的一部分。

我把你的 buggy 关系的定义放在这里,如果其他人需要这个:

/**
 * Parent criteriagroup
 * @var \Innova\PathBundle\Entity\Criteriagroup
 *
 * @ORM\ManyToOne(targetEntity="Criteriagroup", inversedBy="children", cascade={"all"})
 * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
 */
protected $parent;

/**
 * Children criteriagroup
 * @var \Doctrine\Common\Collections\ArrayCollection
 *
 * @ORM\OneToMany(targetEntity="Criteriagroup", mappedBy="parent", indexBy="id", cascade={"persist", "remove"})
 * @ORM\OrderBy({"order" = "ASC"})
 */
protected $children;

为了完成这项工作,您需要替换:

@ORM\JoinColumn(name="parent_id", referencedColumnName="id")

来自

@ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")

通过添加这个,当您删除一个 CriteriaGroup 时,所有 children CriteriaGroup 都将被删除。如果你不想删除children,只需添加onDelete="SET NULL".

希望对您有所帮助。