Я думаю, что нашел проблему. По-видимому, это происходит из-за sqlite, который был неправильно настроен доктриной. Как добавить эту конфигурацию в мое соединение? foreign_keys: ON

я есть несколько классов, использующих признак Taggable для настройки системы тегов, общей для нескольких сущностей доктрин (Project, Note, ...).

Отношения между этими объектами и этими тегами - это отношения ManyToMany, которые я не могу сделать разнонаправленными.

Моя проблема: когда я удаляю объект Project, он удаляется изпроект таблица, но отношения вproject_tag Таблица между этим проектом и тегами не удаляется. Затем, если я создаю новый объект Project, возникает исключение.

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

Taggable

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 = "Каскад", но ничего не работает.

Тем временем я избежал проблемы с этой инструкцией, помещенной перед подавлением.

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

Полный код действия в контроллере:

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

Ответы на вопрос(3)

Ваш ответ на вопрос