manyToMany导致重复输入错误

时间:2011-12-14 15:33:20

标签: php symfony doctrine-orm

我有一个用户实体。那些用户可以在一起成为朋友。所以我定义了一个自我引用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重复条目“1-2”为fey'PRIMARY'

当我签入日志时,我可以看到该学说正在尝试两次执行相同的插入查询。

为了您的信息,我的addFriendList功能

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

我在哪里错了?

3 个答案:

答案 0 :(得分:5)

我终于找到了解决问题的方法。但是,我仍然不知道它是否是Doctrine2缺陷,或者它是否按设计工作。

我需要在添加好友之前坚持我的用户并刷新。

所以我的工作代码是:

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

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

答案 1 :(得分:2)

@Reuven,你写道:

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

好吧,你要两次插入关系。

这应该足够了:

$this->friendList[] = $friend;

答案 2 :(得分:1)

这是因为你没有指定mappedBy(拥有方)和反转方。

查看用户和角色之间的这种多对多关系:

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