web-dev-qa-db-ja.com

Symfony2、Doctrine2-更新を強制-テーブルは多対多のリレーションに既に存在します

カテゴリとタスクの間に1対多の関係を持つ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;
    }
}

および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;
    }
}

だから、doctrine:schema:update --forceエラーが発生します:Table 'symfony.categories' already exists。すべてのキャッシュを削除しようとしましたが、同じ問題があります。何か案が?

M2m関係の場合にのみ問題があります。

[〜#〜] ps [〜#〜]:Googleでこの問題を探していましたが、誰もこの問題に答えていません。問題はどこにあり、どのように解決するかという質問だけがあり、正解はありませんでした。

21
Lkopo

そのデータベースに「categories」という名前のテーブルが既にあるようです。この行@ORM\JoinTable(name="categories")を削除して、試してみてください。

追伸「カテゴリ」は、実際には結合テーブルの奇妙な名前です。おそらくいくつかの規則に従って、doctrineに名前を付けてください。結合テーブルの一般的な名前はcategory_taskまたはcategory2task自明であるため。何もありませんthat重要です、私が良いと思うものを提案しようとしています。

17
Igor Pantović

問題は、doctrineは既存のテーブルがどのように使用されるべきかを理解していないということです。しかし、彼に助けを与えることができます。

次の2つのオプションがあります。

  • 既存のテーブルは気にしません:簡単です。@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;
    ...
}

および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;            
...

そうすることで、doctrineエラーなしでテーブルを維持することができます。

7
Ben Tazulev

私の知る限り、これに対する私の修正は、テーブル名に関する大文字と小文字の区別の問題でした。 Doctrine Usersテーブルとusersテーブルを作成させてください。ただし、その後はmigrations:diffまたはmigrations:migrateで停止します。

-vvvオプションを使用して、このエラーメッセージの詳細を取得しました。 Doctrineが現在のデータベースのスキーマの独自の内部表現をロードしているときにエラーが発生するようです。したがって、現在のデータベースにDoctrine (同一で大文字と小文字を区別しない2つのテーブルのように)理解しないと、この方法で爆発します。

上記の回答のほとんどは、エラーがコードにあると仮定していますが、私の場合はデータベースにありました。

3
willbradley

各バンドルの他のエンティティをチェックした後、同じ問題を修正します。これに注意してください。

0
Jean-Luc Barat

同じエンティティ(以下の例のユーザー)をターゲットとする2つのManyToManyでこのエラーが発生しました。

テーブル名を作成するにはdoctrine=エンティティとターゲットエンティティ名を使用します。

だから私の場合、2回の表thread_userを作成しようとしていました

これをデバッグするのは簡単です。 '@ORM\JoinTable'注釈を使用して、テーブル名を指定するだけです。

動作する例を次に示します。

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\User")
 * @ORM\JoinTable(name="thread_participant")
 */
private $participants;

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\User")
 * @ORM\JoinTable(name="thread_recipient")
 */
private $recipients;
0
Kaizoku Gambare

プロキシディレクトリ内にすべてをドロップしようとします。

0
zinovyev

Symfony4.1移行バージョンを使用して移行を強制できます

doctrine:migrations:execute <migration version>

ex

移行用version123456.php 使用する

doctrine:migrations:execute 123456
0
Sakhri Houssem

別のテーブル名を使用して、プロジェクトで検索できます。 Maby be demo、私はそれを考える...私の中国語英語を申し訳ありません!

0
user5164320