Alberto
Alberto

Reputation: 441

Symfony2 and doctrine: multiple relationships between two classes

I am new to Symfony2 and Doctrine.
I have two classes: User and Book. Each user can like very much, quite, or dislike every book in the database.

In order to describe this kind of association, I defined three different ManyToMany relationships between the two classes. Here is an extract of my code:

Here is class User

<?php

namespace MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="MyBundle\Entity\UserRepository")
 */
class User
{
   /**
    * @var integer
    *
    * @ORM\Column(name="id", type="integer")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    private $id;

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

   /**
    * @ORM\ManyToMany(targetEntity="Book", inversedBy="user_likemuch")
    * @ORM\JoinColumn(name="book_id", referencedColumnName="id")
    */
    protected $books_likemuch;

   /**
    * @ORM\ManyToMany(targetEntity="Book", inversedBy="user_likequite")
    * @ORM\JoinColumn(name="book_id", referencedColumnName="id")
    */
    protected $books_likequite;

   /**
    * @ORM\ManyToMany(targetEntity="Book", inversedBy="user_dislike")
    * @ORM\JoinColumn(name="book_id", referencedColumnName="id")
    */
    protected $books_dislike;

    public function __construct()
    {
        $this->books_likemuch = new ArrayCollection();
        $this->books_likequite = new ArrayCollection();
        $this->books_dislike = new ArrayCollection();

    }

}


And here is class Book:

<?php

namespace MyBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Book
 *
 * @ORM\Table(name="book")
 * @ORM\Entity(repositoryClass="MyBundle\Entity\BookRepository")
 */
class Book
{
   /**
    * @var integer
    *
    * @ORM\Column(name="id", type="integer")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    private $id;

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

   /**
    * @ORM\ManyToMany(targetEntity="User", mappedBy="books_likemuch")
    */
    protected $user_likemuch;

   /**
    * @ORM\ManyToMany(targetEntity="User", mappedBy="books_likequite")
    */
    protected $user_likequite;

   /**
    * @ORM\ManyToMany(targetEntity="User", mappedBy="books_dislike")
    */
    protected $user_dislike;


    public function __construct() {
        $this->user_likemuch = new ArrayCollection();
        $this->user_likequite = new ArrayCollection();
        $this->user_dislike = new ArrayCollection();
    }

}


However, when I try to update the schema of the database through

php app/console doctrine:schema:update --force

I get the following error:

[Doctrine\DBAL\Schema\SchemaException]
The table with name 'XXX/myproject/app/data/users.user_book' already exists.



Actually, I do not even understand if I an describing the relationship in a wrong way, or if doctrine cannot manage multiple relationships between two classes.
Does anyone have any suggestion?
Thanks in advance!

Upvotes: 3

Views: 2405

Answers (1)

Leo Bedrosian
Leo Bedrosian

Reputation: 3799

Doctrine can indeed manage multiple relationships. The classic example is between Users and Roles. The problem here is that you're trying to create multiple ManyToMany relationships between the same two entities. What Doctrine will do to manage these relationships is create a "join" table using the convention table1_table2, or in your case "user_book". So the reason you are getting the Doctrine error is ostensibly because it's attempting to create the same table 3 times.

I think what you want to do is have 3 separate ManyToMany "join" tables, one for likemuch, likequite, and dislike. So try specifying the join table for each association and see if that helps. Ex:

/**
 * @ORM\ManyToMany(targetEntity="Book", inversedBy="user_likemuch")
 * @ORM\JoinColumn(name="book_id", referencedColumnName="id")
 * @ORM\JoinTable(name="user_book_likemuch")
 */
protected $books_likemuch;

See the section on bi-directional association mapping for ManyToMany relationships: Doctrine Association Mapping

Upvotes: 3

Related Questions