从多对多表中删除记录doctrine symfony 2

I can add record to many to many table tag_post successfully but I'm not able to remove any records from tag_post. Please bear in mind I only want to remove records from tag_post not the record from table post itself.

I have 3 tables post,tag and tag_post. tables tag_post contains relation between post and tag. the fields in table tag_post are :

  • tag_id
  • post_id

Mapping file for post:

    oneToMany:
    tagPostAssociations:
        targetEntity: Mockizart\Bundle\BlogBundle\Entity\MockblogTagPost
        mappedBy: "post"
        cascade: ["persist","remove"]

Mapping file for tag:

    oneToMany:
    tagPostAssociations:
        targetEntity: Mockizart\Bundle\BlogBundle\Entity\MockblogTagPost
        mappedBy: "tag"
        cascade: ["persist","remove"]

Mapping file for tag_post:

    manyToOne:
    post:
        associationKey: true
        targetEntity: Mockizart\Bundle\BlogBundle\Entity\MockblogPost
        inversedBy: "tagPostAssociations"
    tag:
        targetEntity: Mockizart\Bundle\BlogBundle\Entity\MockblogTag
        inversedBy: "tagPostAssociations"

My code for test:

    $post = $this->getDoctrine()->getManager()->find('MockizartBlogBundle:MockblogPost',6);
    $b = $this->getDoctrine()->getManager()->find('MockizartBlogBundle:MockblogTagPost',['tagId' => 20,'postId' => 6]);
    $post->removeTagPostAssociation($b);
    $this->getDoctrine()->getManager()->persist($post);
    $this->getDoctrine()->getManager()->flush();

My tag_post entity:

public function __construct($tag, $post)
{
    $this->tagId = $tag->getId();
    $this->postId = $post->getId();
    $this->post = $post;
    $this->tag = $tag;
}

My post entity:

public  $tagPostAssociations;

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

public function addTagPostAssociation(MockblogTagPost $tagPostAssociations)
{
    $newTag = $tagPostAssociations;
    $this->newTags[$newTag->getTagId().$newTag->getPostId()] = $newTag;
    $hasTagPost = $this->hasTagPost($newTag);

    if (!$hasTagPost) {
        $this->tagPostAssociations[] = $tagPostAssociations;
    }

    return $this;
}


public function removeTagPostAssociation(MockblogTagPost $tagPost)
{
    $this->tagPostAssociations->removeElement($tagPost);


    return $this;
}

public function getTagPostAssociations()
{
    return $this->tagPostAssociations;
}

I only post codes that I think related to the case. if you want to see more code, please let me know.

I can't test your setup, however I believe you've mixed up your understanding of the cascade attribute with Doctrine. See, if you did something like:

$post = $this->getDoctrine()->getManager()->find('MockizartBlogBundle:MockblogPost',6);
$this->getDoctrine()->getManager()->remove($post);
$this->getDoctrine()->getManager()->flush();

Then Doctrine would recognize that you are deleting the $post in question and would cascade operations to all of the associations that have the "remove" cascade rule defined, which would delete the tag_post entry in question. However you're not deleting your $post, so you must manually remove the tag_post after taking it out of your object:

$post = $this->getDoctrine()->getManager()->find('MockizartBlogBundle:MockblogPost',6);
$b = $this->getDoctrine()->getManager()->find('MockizartBlogBundle:MockblogTagPost',['tagId' => 20,'postId' => 6]);
$post->removeTagPostAssociation($b);
// This may need to come after the persist, haven't tested
$this->getDoctrine()->getManager()->remove($b);
$this->getDoctrine()->getManager()->persist($post);
$this->getDoctrine()->getManager()->flush();

This is obviously cumbersome if you're constantly removing entries, so perhaps an event listener could automate this process for you.

One other thing to note is that you may be able to get away with just removing the tag_post and not touching your post or tag objects at all:

$b = $this->getDoctrine()->getManager()->find('MockizartBlogBundle:MockblogTagPost',['tagId' => 20,'postId' => 6]);
$this->getDoctrine()->getManager()->remove($b);
$this->getDoctrine()->getManager()->flush();

Reason being is that all of the foreign reference columns "live" in the tag_post table, meaning there would be no integrity violations by simply removing a ManyToMany reference. Only thing is any loaded post or tag object would have out-of-date tagPostAssociations