Доктрина 2 - Об обновлении дубликата ключа

0

У меня есть User Entity, связанная с объектом Role, используя таблицу со многими для многих.

Моя проблема заключается в том, когда я приступаю к ее обновлению.

Это вызывает следующую ошибку:

An exception occurred while executing 'INSERT INTO user_role (user_id, role_id) VALUES (?, ?)' with params [38, 3]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '38-3' for key 'PRIMARY'

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

Присоедините схему таблицы, которая приведена ниже.

+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| user_id | int(11) | NO   | PRI | NULL    |       |
| role_id | int(11) | NO   | PRI | NULL    |       |
+---------+---------+------+-----+---------+-------+

У моего объекта User есть метод setRoles(), который добавит роль в ArrayCollection, а затем доктрина попытается выполнить вставку.

Так что, я думаю, я пытаюсь спросить, есть ли метод дублирования ключа в доктрине?

Или может кто-то любезно дать мне какое-то направление о том, как достичь этого, даже если это означает восстановление схемы.

Я новичок в доктрине, я следил за новичком и все еще размышлял над документацией.

РЕДАКТИРОВАТЬ

<?php
namespace Brs\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;

class User implements UserInterface, \Serializable
{
    private $id;
    private $username;
    private $fname;
    private $lname;
    private $email;
    private $mobile;
    private $active;
    private $mentor;
    private $initialized;
    private $roles;
    private $password;
    private $tempPassword;

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

    public function getTempPassword(){
        return $this->tempPassword;
    }

    public function setTempPassword($tempPassword){
        $this->tempPassword = $tempPassword;

        return $this;
    }

    public function getUsername(){
        return $this->username;
    }

    public function getSalt(){
        return null;
    }

    public function getPassword(){
        return $this->password;
    }

    public function getRoles(){
        return $this->roles->toArray();
    }

    public function getRole(){
        return $this->roles;
    }

    public function setRoles($roles){
        $this->roles[] = $roles;
        return $this;
    }

    public function eraseCredentials(){

    }

    public function serialize(){
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
        ));
    }

    public function unserialize($serialized){
        list(
                $this->id,
                $this->username,
                $this->password,
            ) = unserialize($serialized);
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set username
     *
     * @param string $username
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    /**
     * Set fname
     *
     * @param string $fname
     * @return User
     */
    public function setFname($fname)
    {
        $this->fname = $fname;

        return $this;
    }

    /**
     * Get fname
     *
     * @return string 
     */
    public function getFname()
    {
        return $this->fname;
    }

    /**
     * Set lname
     *
     * @param string $lname
     * @return User
     */
    public function setLname($lname)
    {
        $this->lname = $lname;

        return $this;
    }

    /**
     * Get lname
     *
     * @return string 
     */
    public function getLname()
    {
        return $this->lname;
    }

    /**
     * Set email
     *
     * @param string $email
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set mobile
     *
     * @param string $mobile
     * @return User
     */
    public function setMobile($mobile)
    {
        $this->mobile = $mobile;

        return $this;
    }

    /**
     * Get mobile
     *
     * @return string 
     */
    public function getMobile()
    {
        return $this->mobile;
    }

    /**
     * Set active
     *
     * @param boolean $active
     * @return User
     */
    public function setActive($active)
    {
        $this->active = $active;

        return $this;
    }

    /**
     * Get active
     *
     * @return boolean 
     */
    public function getActive()
    {
        return $this->active;
    }

    /**
     * Set mentor
     *
     * @param boolean $mentor
     * @return User
     */
    public function setMentor($mentor)
    {
        $this->mentor = $mentor;

        return $this;
    }

    /**
     * Get mentor
     *
     * @return boolean 
     */
    public function getMentor()
    {
        return $this->mentor;
    }

    /**
     * Set initialized
     *
     * @param \DateTime $initialized
     * @return User
     */
    public function setInitialized($initialized)
    {
        $this->initialized = $initialized;

        return $this;
    }

    /**
     * Get initialized
     *
     * @return \DateTime 
     */
    public function getInitialized()
    {
        return $this->initialized;
    }

    /**
     * Set password
     *
     * @param string $password
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }
    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $targetEntity;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $inversedBy;


    /**
     * Add targetEntity
     *
     * @param \Brs\UserBundle\Entity\R $targetEntity
     * @return User
     */
    public function addTargetEntity(\Brs\UserBundle\Entity\R $targetEntity)
    {
        $this->targetEntity[] = $targetEntity;

        return $this;
    }

    /**
     * Remove targetEntity
     *
     * @param \Brs\UserBundle\Entity\R $targetEntity
     */
    public function removeTargetEntity(\Brs\UserBundle\Entity\R $targetEntity)
    {
        $this->targetEntity->removeElement($targetEntity);
    }

    /**
     * Get targetEntity
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTargetEntity()
    {
        return $this->targetEntity;
    }

    /**
     * Add inversedBy
     *
     * @param \Brs\UserBundle\Entity\u $inversedBy
     * @return User
     */
    public function addInversedBy(\Brs\UserBundle\Entity\u $inversedBy)
    {
        $this->inversedBy[] = $inversedBy;

        return $this;
    }

    /**
     * Remove inversedBy
     *
     * @param \Brs\UserBundle\Entity\u $inversedBy
     */
    public function removeInversedBy(\Brs\UserBundle\Entity\u $inversedBy)
    {
        $this->inversedBy->removeElement($inversedBy);
    }

    /**
     * Get inversedBy
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getInversedBy()
    {
        return $this->inversedBy;
    }

    /**
     * Add roles
     *
     * @param \Brs\UserBundle\Entity\Role $roles
     * @return User
     */
    public function addRole(\Brs\UserBundle\Entity\Role $roles)
    {
        $this->roles[] = $roles;

        return $this;
    }

    /**
     * Remove roles
     *
     * @param \Brs\UserBundle\Entity\Role $roles
     */
    public function removeRole(\Brs\UserBundle\Entity\Role $roles)
    {
        $this->roles->removeElement($roles);
    }
}

Роль:

<?php
namespace Brs\UserBundle\Entity;

use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

class Role implements RoleInterface{
    private $id;
    private $name;
    private $role;
    private $users;

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

    public function getRole(){
        return $this->role;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Role
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set role
     *
     * @param string $role
     * @return Role
     */
    public function setRole($role)
    {
        $this->role = $role;

        return $this;
    }

    /**
     * Add users
     *
     * @param \Brs\UserBundle\Entity\User $users
     * @return Role
     */
    public function addUser(\Brs\UserBundle\Entity\User $users)
    {
        $this->users[] = $users;

        return $this;
    }

    /**
     * Remove users
     *
     * @param \Brs\UserBundle\Entity\User $users
     */
    public function removeUser(\Brs\UserBundle\Entity\User $users)
    {
        $this->users->removeElement($users);
    }

    /**
     * Get users
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getUsers()
    {
        return $this->users;
    }
}

благодаря

Адам

  • 0
    Ну, это подразумевает, что вы снова устанавливаете роль для того же пользователя (то есть, тот же role_id и тот же user_id) - почему вы пытаетесь это сделать? Более того, это таблица соединения, так какое действие UPDATE она предпримет? Вы должны показать нам своих пользователей и роли.
  • 0
    Покажите нам код, который вызывает это
Показать ещё 6 комментариев
Теги:
doctrine2

2 ответа

0
Лучший ответ

@Adam. Есть функции на ArrayCollection для его проверки. Первые два бы contains и indexOf - они используют in_array и array_search внутренне, так что я думаю, что вы нуждаетесь в роли вы передаете, чтобы быть тем же экземпляр, то будет в тождественном, который был загружен в коллекцию - потому что он проверяет на равенство ссылок. Третий, exists позволяет вам пройти в Closure для использования в качестве функции сравнения.

Я бы использовал один из этих методов внутри метода hasRole для объекта User:

public function hasRole(Role $role) {
    return $this->getRoles()->contains($role);
}

Если по какой-то причине вам нужно использовать exists вариант, это может выглядеть так:

public function hasRole(Role $role) {
    return $this->getRoles()->exists(function($key, $entity) use ($role) {
         return $entity->getId() === $role->getId();
    });
}

Вы могли бы, конечно, изменить этот метод, чтобы сравнить больше полей или что-то еще, или позволить вам передать в набор полей для сравнения, но это не похоже на необходимость в этом случае.

  • 0
    Отличный ответ, спасибо.
1

Спасибо за все Ваши ответы :-).

Хорошо из-за моего непонимания, я не знал о составных ключах mysql благодаря @prodigitalson для указания этого.

Вот что я реализовал в своем User Entity, чтобы проверить, что составные ключи не существуют, если они не выполняют эту вставку. Благодаря @kmlnvm за руководство по этому.

private $roleIds = array();

public function setRoles($role){
    if($role !== null){
        foreach($this->getRoles() as $currentRole){
            $this->roleIds[] = $currentRole->getId();
        }

        if(!in_array($role->getId(),$this->roleIds)){
            $this->roles[] = $role;
        }
    }

    return $this;
}

Я хотел бы указать, что я реализовал, это хороший способ сделать это?

благодаря

Адам

  • 0
    Не нужно зацикливаться на этом, есть методы для этого на ArrayCollection . Смотри мой ответ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню