drvvepadi289421028 2014-11-28 02:39
浏览 13
已采纳

从多对多表中删除记录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.

  • 写回答

1条回答 默认 最新

  • doudang1052 2014-11-28 03:01
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程