Symfony Doctrine2 manyToMany关系不删除 - 特定于SQLite [英] Symfony Doctrine2 manyToMany relationship not removed - Specific to SQLite

查看:200
本文介绍了Symfony Doctrine2 manyToMany关系不删除 - 特定于SQLite的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个类使用Taggable特征来建立一些标准系统,这些标签系统与几个教义实体(Project,Note,...)共同。

I have several classes using a Taggable trait to set up a tag system common to several doctrine entities (Project, Note, ...).

这些实体和这些标签是一个ManyToMany关系,我无法进行多方向。

The relationship between these entities and these tags is a ManyToMany relationship that I can not make multi-directional.

我的问题:当我删除一个项目实体时,它从项目表,但此项目与标记之间的 project_tag 表之间的关系不会被删除。然后,如果我创建一个新的项目实体,将抛出异常。

My problem: When I delete a Project entity, it is removed from the project table, but the relationships in the project_tag table between this project and the tags are not deleted. Then, if I create a new Project entity, an exception is thrown.

An exception exists while executing 'INSERT INTO project_tag (project_id, tag_id) VALUES (?,?)' With params [2, 4]:

SQLSTATE [23000]: Integrity constraint violation: 19 UNIQUE constraint failed: project_tag.project_id, project_tag.tag_id

实体:

标签

/**
 * Tag
 *
 * @ORM\Table(name="tag")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\TagRepository")
 */
class Tag
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, unique=true)
     */
    private $name;

    /**
     * @ORM\Column(name="last_use_at", type="datetime", nullable=false)
     * @var \DateTime
     */
    private $lastUseAt;


    public function __construct()
    {
        $this->lastUseAt = new \DateTime();
    }

    public function __toString()
    {
        return $this->name;
    }

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Tag
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @return \DateTime
     */
    public function getLastUseAt(): \DateTime
    {
        return $this->lastUseAt;
    }

    /**
     * @param \DateTime $lastUseAt
     */
    public function setLastUseAt(\DateTime $lastUseAt)
    {
        $this->lastUseAt = $lastUseAt;
    }
}

可标注

trait Taggable
{

 /**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Tag", cascade={"persist"})
 */
protected $tags;

/**
 * Add tag
 *
 * @param Tag $tag
 *
 * @return $this
 */
public function addTag(Tag $tag)
{
    $tag->setLastUseAt(new \DateTime());
    $this->tags[] = $tag;

    return $this;
}

/**
 * Remove tag
 *
 * @param Tag $tag
 */
public function removeTag(Tag $tag)
{
    $this->tags->removeElement($tag);
}

/**
 * Get tags
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getTags()
{
    return $this->tags;
}
}

项目

/**
 * Project
 *
 * @ORM\Table(name="project")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProjectRepository")
 */
class Project
{
    use Taggable;
}

笔记

class Note
{
    use Taggable;
}

这是唯一的解决方案还是我的注释不完整/不正确?
我尝试使用JoinColumns,JoinTable和onDelete =cascade,但没有任何作用。

Is this the only solution or is my annotation incomplete / incorrect? I tried with JoinColumns, JoinTable and onDelete = "cascade" but nothing works.

在此期间,我躲避了在禁令之前的这个指令的问题。

In the meantime, I dodged the problem with this instruction placed before the suppresion.

$project->getTags()->clear ();

控制器中的操作的完整代码:

Full code of the action in the controller :

/**
 * @Route("/project/{id}/delete", name="project_delete")
 */
public function deleteAction($id) {
    $em = $this->getDoctrine()->getManager();
    $project = $em->getRepository('AppBundle:Project')->find($id);

    if(!$project) {
        return $this->redirectToRoute('index');
    }

    $project->getTags()->clear();
    $em->remove($project);
    $em->flush();

    return $this->redirectToRoute('index');
}


推荐答案

我设法解决了问题。这是我为SQLite连接工作的解决方案。

I managed to fix the problem. Here's my solution working for SQLite conections.

创建一个监听kernel.request事件的eventListener:

Create an eventListener listening on the kernel.request event :

namespace AppBundle\EventListener;


use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class RequestListener
{
    /**
     * @var Registry
     */
    private $doctrine;

    public function __construct(Registry $doctrine)
    {
        $this->doctrine = $doctrine;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $this->doctrine->getConnection()->exec('PRAGMA foreign_keys = ON');
    }
}

服务声明

  app.event_listener.request_listener:
        class: AppBundle\EventListener\RequestListener
        arguments:
            - '@doctrine'
        tags:
            - { name: kernel.event_listener, event: kernel.request }

这篇关于Symfony Doctrine2 manyToMany关系不删除 - 特定于SQLite的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆