Symfony2,Doctrine2 - 强制更新 - 表已存在于多对多关系中

Lko*_*opo 21 php symfony doctrine-orm

在我成功创建了TaskBundle并在类别和任务之间建立了一对多关系后,现在我正在尝试创建一个具有多对多关系的新TaskBundle.我在这个关系中检查复选框也有问题,但现在它不是主要问题(也许在解决之后).我删除了所有表,这是TaskBundle使用并尝试创建一个新的,但这里有问题(底部的描述).

我的任务对象:

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="tasks") 
 */
class Task
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;              

    /**
     * @ORM\Column(type="string", length=200)    
     * @Assert\NotBlank(
     *      message = "Task is empty"      
     * )    
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Task is too short"         
     * )     
     */     
    protected $task;

    /**
     * @ORM\Column(type="datetime")    
     * @Assert\NotBlank()
     * @Assert\Type("\DateTime")
     */
    protected $dueDate;

    /**
     * @Assert\True(message = "You have to agree.")    
     */         
    protected $accepted;

    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
     * @ORM\JoinTable(name="categories")                         
     */
    protected $category;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->category = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

    /**
     * Set task
     *
     * @param string $task
     * @return Task
     */
    public function setTask($task)
    {
        $this->task = $task;

        return $this;
    }

    /**
     * Get task
     *
     * @return string 
     */
    public function getTask()
    {
        return $this->task;
    }

    /**
     * Set dueDate
     *
     * @param \DateTime $dueDate
     * @return Task
     */
    public function setDueDate($dueDate)
    {
        $this->dueDate = $dueDate;

        return $this;
    }

    /**
     * Get dueDate
     *
     * @return \DateTime 
     */
    public function getDueDate()
    {
        return $this->dueDate;
    }

    /**
     * Add category
     *
     * @param \Acme\TaskBundle\Entity\Category $category
     * @return Task
     */
    public function addCategory(\Acme\TaskBundle\Entity\Category $category)
    {
        $this->category[] = $category;

        return $this;
    }

    /**
     * Remove category
     *
     * @param \Acme\TaskBundle\Entity\Category $category
     */
    public function removeCategory(\Acme\TaskBundle\Entity\Category $category)
    {
        $this->category->removeElement($category);
    }

    /**
     * Get category
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getCategory()
    {
        return $this->category;
    }
}
Run Code Online (Sandbox Code Playgroud)

和Category对象

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="categories") 
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")             
     */
    protected $id; 

    /**
     * @ORM\Column(type="string", length=200, unique=true)   
     * @Assert\NotNull(message="Categories cannot be empty", groups = {"adding"})                   
     */         
    protected $name;  

    /**
     * @ORM\ManyToMany(targetEntity="Task", mappedBy="category")
     */
    private $tasks;            


    public function __toString()
    {
        return strval($this->name);
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

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

        return $this;
    }

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

    /**
     * Add tasks
     *
     * @param \Acme\TaskBundle\Entity\Task $tasks
     * @return Category
     */
    public function addTask(\Acme\TaskBundle\Entity\Task $tasks)
    {
        $this->tasks[] = $tasks;

        return $this;
    }

    /**
     * Remove tasks
     *
     * @param \Acme\TaskBundle\Entity\Task $tasks
     */
    public function removeTask(\Acme\TaskBundle\Entity\Task $tasks)
    {
        $this->tasks->removeElement($tasks);
    }

    /**
     * Get tasks
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTasks()
    {
        return $this->tasks;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,在我把doctrine:schema:update --force我得到错误之后:Table 'symfony.categories' already exists.我试图删除所有缓存,但同样的问题.任何的想法?

唯一的问题是,如果它是m2m关系.

PS:我在谷歌寻找这个问题,但没有人回答这个问题.只有问题,但没有正确的答案,问题是什么以及如何解决它.

Igo*_*vić 17

看起来您已经在该数据库中拥有名为"categories"的表.删除此行@ORM\JoinTable(name="categories")并尝试不使用它.

PS"类别"实际上是连接表的奇怪名称.您应该遵循一些约定,并让学说命名.连接表的通用名称是category_task或者category2task因为它们更加不言自明.没有什么重要的,只是想暗示什么,我认为很好的做法.

  • 这是错误的答案.如果删除JoinTable - 它将创建更多一个表,其中包含一个manyToMany Relation. (3认同)
  • 它将由Doctrine自动创建.因为它知道它是ManyToMany关系并且需要创建它. (2认同)

小智 7

问题是,学说不理解你的现有表应该如何使用.但你可以给他一些帮助.

您有两种选择:

  • 你不关心现有的表:简单,你可以删除@ORM\JoinTable(name="categories")注释,而doctrine会创建另一个表等.

  • 您希望保留现有表,这听起来很合理:您必须通过添加@ORM\JoinColumn注释在注释中更明确.

这是一个例子:

class 

<?php
...
/**
 * @ORM\Entity
 * @ORM\Table(name="tasks") 
 */
class Task
{
    ...
    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
     * @ORM\JoinTable(name="categories",
     *       joinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")},
     *       inverseJoinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id")})                         
     */
    protected $category;
    ...
}
Run Code Online (Sandbox Code Playgroud)

和Category对象

<?php
...    
/**
 * @ORM\Entity
 * @ORM\Table(name="categories") 
 */
class Category
{
    ...
    /**
     * @ORM\ManyToMany(targetEntity="Task", mappedBy="category")
     * @ORM\JoinTable(name="categories",
     *       joinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id")},
     *       inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")})
     */
    private $tasks;            
...
Run Code Online (Sandbox Code Playgroud)

这样做,您将能够保持您的表没有任何学说错误.

  • `@ORM\JoinTable`被忽略,并且在不拥有一侧时完全没有必要(如果我没记错的话,使用`mappedBy`属性).此外,它可能导致开发人员忘记在第二个位置更新它,所以你不应该真正放置它两次. (3认同)