Herr Nentu'
Herr Nentu'

Reputation: 1506

Doctrine ArrayCollection remove element not working

Even if the object is correctly updated it seems that the data is not persisted and I don't get it why.

Here is my Entity:

Article.php

/**
 * @var AttributeInArticle
 *
 * @ORM\OneToMany(
 *      targetEntity="XXX\DatabaseBundle\Entity\AttributeInArticle",
 *      mappedBy="article"
 * )
 */
private $attributeInArticles;

....

public function __construct()
{
    $this->attributeInArticles = new ArrayCollection();
}


/**
 * @return AttributeInArticle
 */
public function getAttributeInArticles()
{
    return $this->attributeInArticles;
}

public function addAttributeInArticle(AttributeInArticle $attributeInArticles)
{
    $this->attributeInArticles[] = $attributeInArticles;

    return $this;
}

public function removeAttributeInArticle(AttributeInArticle $attributeInArticles)
{
    $this->attributeInArticles->removeElement($attributeInArticles);
}

AttributeInArticle.php

/**
 * @var  Attribute
 *
 * @ORM\ManyToOne(
 *      targetEntity="XXX\DatabaseBundle\Entity\Attribute",
 *      inversedBy="attributeInArticles"
 * )
 * @ORM\JoinColumns({
 *     @ORM\JoinColumn(
 *          name="attribute_id",
 *          referencedColumnName="id")
 * })
 */
private $attribute;

/**
 * @var Article
 *
 * @ORM\ManyToOne(
 *      targetEntity="XXX\DatabaseBundle\Entity\Article",
 *      inversedBy="attributeInArticles"
 * )
 * @ORM\JoinColumns({
 *       @ORM\JoinColumn(
 *          name="article_id",
 *          referencedColumnName="id"
 *      )
 * })
 *
 */
private $article;

/**
 * @return Attribute
 */
public function getAttribute()
{
    return $this->attribute;
}

/**
 * @param Attribute $attribute
 */
public function setAttribute($attribute)
{
    $this->attribute = $attribute;
}

+ getter & setter for $article

And in the controller I am calling it like this:

$article->removeAttributeInArticle($attributeInArticle);

If I dumpthe $article object before and after the remove action the $article object has the corect data in it. That means that $attributeInArticle was removed.

But for some reason it does not persist this data.

Upvotes: 5

Views: 12979

Answers (2)

DonCallisto
DonCallisto

Reputation: 29922

The answer is easy here.

You are removing an Attribute from an Article and the persisting/flushing Article. If you look to your mappings you'll notice easily that the relationship between Article and AttributeInArticole is owned by the latter.

When you do flushing operations, doctrine, for performance reasons, "looks" only to owning side of a relationship and for changes in it: if nothing changed there's no need to write it in db.

So, what you can do here, is to remove the $attributeInArticle directly without worry about Article entity.

So, basically

$em = $this
    ->getDoctrine()
    ->getManager();

$em->remove($attributeInArticle);
$em->flush();

Another option is to use orphanRemoval on $attribueInArticles of your Article entity.

So, basically,

//Article.php

/**
 * @var AttributeInArticle
 *
 * @ORM\OneToMany(
 *      targetEntity="XXX\DatabaseBundle\Entity\AttributeInArticle",
 *      mappedBy="article",
 *      orphanRemoval=true
 * )
 */
private $attributeInArticles;

and

$article->removeAttributeInArticle($attributeInArticle);

Upvotes: 9

po_taka
po_taka

Reputation: 1856

You need cascade={"remove"}

/**
 * @var AttributeInArticle
 *
 * @ORM\OneToMany(
 *      targetEntity="XXX\DatabaseBundle\Entity\AttributeInArticle",
 *      mappedBy="article",
 *      cascade={"remove"}
 * )
 */

Read doctrine documentation: 8. Working with Associations. Also check "Orphan Removal"

Upvotes: 0

Related Questions