1

I've got these entities (relevant part for the problem) :

 /**
 * 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;
}

and

/**
 * 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;
}

When i try to delete a criteriagroup, i want to delete the attached criterion. I've got this error :

 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`))

So i've read some post like this our this one and the suggested solution is the solution is to use a onDelete="SET NULL" on the joinColumn in the ManyToOne side, which i did. But i still get this error.

What could be wrong ? Thank you

EDIT :

@RaulFerriz : Thank you for the answer. If i try your modifications : with cascade={"persist"} instead of cascade={"all"} in Criterion, i still have the same error.

But if i remove entirely the cascade in Criterion, i have :

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` 

that seems to mean the cascade={"persist"} is needed.

I don't knwon what to try next. I do a doctrine:schema:update after each modification.

Community
  • 1
  • 1
Overdose
  • 585
  • 7
  • 30
  • 1
    Looks like you have a parent/child relation defined in Criteriagroup? You will need to set cascade on it as well. – Cerad Sep 07 '15 at 16:49
  • @Cerad : isn't it what i did ? ```@ORM\OneToMany(targetEntity="Innova\PathBundle\Entity\Criterion", mappedBy="criteriagroup", indexBy="id", cascade={"persist", "remove"})``` – Overdose Sep 08 '15 at 07:20

2 Answers2

3

Your problem is not in your relation Criteriagroup and Criteria.

If you check the SQL error, the constraint that failed is for the field parent_id. Which is part of your Criteriagroup / Criteriagroup relation.

I put here the definition of your buggy relation, if someone else need this :

/**
 * 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;

In order to make this work, you need to replace :

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

by

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

By adding this, when you will delete a CriteriaGroup, all children CriteriaGroup will be deleted. If you don't want to delete children, just add onDelete="SET NULL".

Hope it helps.

Elorfin
  • 2,487
  • 1
  • 27
  • 50
0

As you have defined the entities, when you try to remove a "Criterion" the entity Criteriongroup will also be deleted. That is not what you are attempting to achieve.

Try with this

/** * 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; }

And this /** * 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; }

Basically, clean up Criterion entity from cascading all, at most I suppose you will need {cascade="persist"} at this entity that means: when Criterion is persisted, persist also Criteriagroup linked with it.

RaulFerriz
  • 33
  • 6