2011-12-14 9 views
5

Ho un'entità Utente. E quegli utenti possono essere amici insieme. Così ho definito un'associazione unidirezionale manyToMany autoreferenziale (perché c'è sempre reciprocità è amicizia, giusto?).manyToMany causa l'errore di immissione duplicata

un pezzo della mia entità utente in YML

manyToMany: 
    friendList: 
    targetEntity: User 
    joinTable: 
     name: user_friend 
     joinColumns: 
     user_id: 
      referencedColumnName: id 
     inverseJoinColumns: 
     friend_id: 
      referencedColumnName: id 
    cascade: [persist] 

Quando chiamo $user->addFriendList($friend), e dopo un persistere e un colore, ho PDOException:

SQLSTATE [23000]: violazione del vincolo di integrità : 1062 Duplicate entry '1-2' per fey 'PRIMARY'

Quando controllo i log, posso vedere che la dottrina sta cercando di xectue la stessa query di inserimento due volte.

Per vostra informazione, la mia funzione addFriendList

public function addFriendList(User $friend) 
{ 
    if (!$this->friendList->contains($friend)) { 
     $this->friendList[] = $friend; 
     $friend->addFriendList($this); 
    } 
} 

dove sto male qui?

risposta

4

Ho finalmente trovato una soluzione al mio problema. Tuttavia non so ancora se si tratta di un difetto Doctrine2 o se funziona come progettato.

Ho bisogno di mantenere il mio utente e il colore prima di aggiungere amici.

Quindi il mio codice di lavoro è:

$em->persist($user); 
$em-flush(); 

$user->addFriendList($friend); 
$em->persist($user); 
$em->flush(); 
2

@Reuven, è scritto:

$this->friendList[] = $friend; 
$friend->addFriendList($this); 

Beh, si sta inserendo il rapporto due volte.

Questo dovrebbe essere sufficiente:

$this->friendList[] = $friend; 
1

È perché non è stato specificato un mappedBy (lato possedere) e inversedBy.

Dai un'occhiata a questo molti-a-molti tra utenti e ruoli:

/** 
* @ORM\Entity 
* @ORM\Table(name="user") 
*/ 
class User 
{ 

    /** 
    * @ORM\ManyToMany(targetEntity="Role", mappedBy="users") 
    * @ORM\JoinTable(name="user_role", 
    *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")} 
    *) 
    */ 
    protected $roles; 

    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->roles = new ArrayCollection(); 
    } 

    /** 
    * Has role 
    * 
    * @param Role $role 
    * @return bool 
    */ 
    public function hasRole(Role $role) 
    { 
     return $this->roles->contains($role); 
    } 

    /** 
    * Add role 
    * 
    * @param Role $role 
    */ 
    public function addRole(Role $role) 
    { 
     if (!$this->hasRole($role)) { 
      $this->roles->add($role); 
      $role->addUser($this); 
     } 
    } 

    /** 
    * Remove roles 
    * 
    * @param Role $role 
    */ 
    public function removeRole(Role $role) 
    { 
     if ($this->hasRole($role)) { 
      $this->roles->removeElement($role); 
      $role->removeUser($this); 
     } 
    } 
} 

.

/** 
* @ORM\Entity 
* @ORM\Table(name="role") 
*/ 
class Role implements RoleInterface 
{ 

    /** 
    * @ORM\ManyToMany(targetEntity="User", inversedBy="roles") 
    * @ORM\JoinTable(name="user_role", 
    *  joinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")} 
    *) 
    */ 
    private $users; 

    public function __construct() 
    { 
     $this->users = new ArrayCollection(); 
    } 

    /** 
    * Has user 
    * 
    * @param User $user 
    * @return bool 
    */ 
    public function hasUser(User $user) 
    { 
     return $this->users->contains($user); 
    } 

    /** 
    * Add user 
    * 
    * @param User $user 
    */ 
    public function addUser(User $user) 
    { 
     if (!$this->hasUser($user)) { 
      $this->users->add($user); 
      $user->addRole($this); 
     } 
    } 

    /** 
    * Remove user 
    * 
    * @param User $user 
    */ 
    public function removeUser(User $user) 
    { 
     if ($this->hasUser($user)) { 
      $this->users->removeElement($user); 
      $user->addRole($this); 
     } 
    } 

    /** 
    * Get users 
    * 
    * @return ArrayCollection 
    */ 
    public function getUsers() 
    { 
     return $this->users; 
    }