manyToMany вызывает ошибку повторяющегося ввода - PullRequest
5 голосов
/ 14 декабря 2011

У меня есть пользовательский объект.И эти пользователи могут быть друзьями вместе.Поэтому я определил самоссылку однонаправленной ассоциации 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' для фея 'ПЕРВИЧНАЯ'

Когда я проверяю журналы, я вижу, что доктрина пытается выполнить один и тот же запрос вставки дважды.

Для вашей информации, моя addFriendList функция

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

Где я здесь не прав?

Ответы [ 3 ]

5 голосов
/ 20 декабря 2011

Я наконец нашел решение своей проблемы. Однако я до сих пор не знаю, является ли это дефектом Doctrine2 или он работает как задумано.

Мне нужно сохранить пользователя и очистить его перед добавлением друзей.

Итак, мой рабочий код:

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

$user->addFriendList($friend);
$em->persist($user);
$em->flush();
2 голосов
/ 17 октября 2013

@ Реувен, ты написал:

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

Ну, вы вставляете отношения дважды.

Этого должно быть достаточно:

$this->friendList[] = $friend;
1 голос
/ 30 июля 2014

Это потому, что вы не указали mappedBy (владеющую сторону) и inversedBy.

Проверьте, как много-много-много отношений между пользователями и ролями:

/**
 * @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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...