2011-12-14 12 views
5

私はUserエンティティを持っています。そしてそれらのユーザーは一緒にお友達になれます。だから、私は自己参照manyToMany一方向の関連付けを定義しました(なぜなら相互主義は常に友好関係であるからです)。manyToManyは重複した入力エラーを引き起こします

YMLの私のユーザエンティティの一部

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

私は$user->addFriendList($friend)を呼び出し、そして持続し、フラッシュ、私が持っているPDOException後:

SQLSTATE [23000]:整合性制約違反:1062 fey 'PRIMARY'の重複エントリ '1-2'

私がログをチェックインすると、ドクトリンが電子メールを送信しようとしていることがわかります同じ挿入クエリを2回xectueします。あなたの情報については

、私addFriendList機能私は間違ってここにいる

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

答えて

4

私は最終的に私の問題の解決策を見つけました。しかし、私はそれがDoctrine2の欠陥であるか、それとも設計通りに動作するかはまだ分かりません。

友だちを追加する前にユーザーを維持してフラッシュする必要があります。

だから私の作業のコードは次のとおりです。

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

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

@Reuven、あなたが書いた:

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

をさて、あなたは二度の関係を挿入しています。

これは十分なはずです:あなたがmappedBy(所有側)とinversedByを指定しなかったので、

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

にです。

チェックアウトユーザーとロールの間に、この多対多の関係:

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