doctrine2:删除具有ManytoMany关系的实体

时间:2016-12-20 08:32:48

标签: php symfony orm doctrine-orm many-to-many

我想知道如果你们可以帮助我。我到处寻找答案,没有任何效果。我有一个实体,用户,有角色,有多对多的关系。我用Doctrine ORM管理它,但问题是当我尝试删除用户时,没有任何反应。我究竟做错了什么?这是代码:

USER:

/**
 * User.
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User implements AdvancedUserInterface, \Serializable
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="username", type="string", length=255, unique=true)
 * @Assert\NotBlank()
 */
private $username;

/**
 * @var string
 *
 * @ORM\Column(name="email", type="string", length=255, unique=true)
 * @Assert\Email()
 */
private $email;

/**
 * @var bool
 *
 * @ORM\Column(name="enabled", type="boolean")
 * @Assert\Type(type="bool")
 */
private $isEnabled;

/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Role", inversedBy="users", cascade={"persist"})
 * @ORM\JoinTable(name="user_role",
 *          joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="cascade")},
 *          inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id", onDelete="cascade")}
 * )
 */
private $roles;

/**
 * @ORM\OneToMany(targetEntity="AppBundle\Entity\MediaCenter", mappedBy="user", cascade={"persist"})
 */
private $mediaCenters;

/**
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Client", cascade={"persist"})
 */
private $clients;

/**
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Account", cascade={"persist"})
 */
private $accounts;

public function __construct()
{
    $this->isEnabled = true;
    $this->roles = new ArrayCollection();
    $this->mediaCenters = new ArrayCollection();
    $this->clients = new ArrayCollection();
    $this->accounts = new ArrayCollection();
}

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

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

    return $this;
}

/**
 * Get username.
 *
 * @return string
 */
public function getUsername()
{
    return $this->username;
}

/**
 * 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 isEnabled.
 *
 * @param bool $isEnabled
 *
 * @return User
 */
public function setIsEnabled($isEnabled)
{
    $this->isEnabled = $isEnabled;

    return $this;
}

/**
 * Get isEnabled.
 *
 * @return bool
 */
public function getIsEnabled()
{
    return $this->isEnabled;
}

public function __toString()
{
    return ''.$this->getUsername();
}

public function getRoles()
{
    return $this->roles->toArray();
}
/**
 * Add roles.
 *
 * @param AppBundle\Entity\Role $roles
 *
 * @return User
 */
public function addRole(AppBundle\Entity\Role $roles)
{
    $roles->addUser($this);

    $this->roles->add($role);
    return $this;
}

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

public function getMediaCenters()
{
    return $this->mediaCenters->toArray();
}

/**
 * Add mediaCenters.
 *
 * @param AppBundle\Entity\MediaCenter $mediaCenters
 *
 * @return User
 */
public function addMediaCenter(AppBundle\Entity\MediaCenter $mediaCenters)
{
    $this->mediaCenters[] = $mediaCenters;

    return $this;
}

/**
 * Remove mediaCenters.
 *
 * @param AppBundle\Entity\MediaCenter $mediaCenters
 */
public function removeMediaCenter(AppBundle\Entity\MediaCenter $mediaCenters)
{
    $this->mediaCenters->removeElement($mediaCenters);
}

public function getClients()
{
    return $this->clients->toArray();
}

/**
 * Add clients.
 *
 * @param AppBundle\Entity\Client $client
 *
 * @return User
 */
public function addClient(AppBundle\Entity\Client $clients)
{
    $this->clients[] = $clients;

    return $this;
}

/**
 * Remove clients.
 *
 * @param AppBundle\Entity\Client $clients
 */
public function removeClient(AppBundle\Entity\Client $clients)
{
    $this->clients->removeElement($clients);
}

public function getAccounts()
{
    return $this->accounts->toArray();
}

/**
 * Add accounts.
 *
 * @param AppBundle\Entity\Account $accounts
 *
 * @return User
 */
public function addAccount(AppBundle\Entity\Account $accounts)
{
    $this->accounts[] = $accounts;

    return $this;
}

/**
 * Remove accounts.
 *
 * @param AppBundle\Entity\Account $accounts
 */
public function removeAccount(AppBundle\Entity\Account $accounts)
{
    $this->accounts->removeElement($accounts);
}

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

/**
 * @see \Serializable::serialize()
 */
 public function serialize()
 {
     return serialize(array(
         $this->id,
     ));
 }   
/**
 * @see \Serializable::unserialize()
 */
 public function unserialize($serialized)
 {
    list(
        $this->id) = unserialize($serialized);
 }
}

作用:

/**
 * @ORM\Table()
 * @ORM\Entity()
 */
class Role implements RoleInterface
{
/**
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id()
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(name="name", type="string", length=45)
 */
private $name;

/**
 * @ORM\Column(name="role", type="string", length=45, unique=true)
 */
private $role;

/**
 * @ORM\ManyToMany(targetEntity="User", mappedBy="roles", cascade={"persist"})
 */
private $users;

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

/**
 * @see RoleInterface
 */
public function getRole()
{
    return $this->role;
}

/**
 * Get id.
 *
 * @return int
 */
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 AppBundle\Entity\User $users
 *
 * @return Role
 */
public function addUser(AppBundle\Entity\User $users)
{
    //$this->users[] = $users;

   // $users->addRole($this);

    if (!$this->users->contains($users)) {
        $this->users->add($users);
    }

    return $this;
}

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

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

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

    foreach ($users as $a) {
        $this->adduser($a);
    }

    return $this;
}

public function __toString()
{
    return ''.$this->getName();
}
}

以下是我尝试删除用户的方法:

public function DeleteUserAction()
{
    $request = $this->getRequest();

    $session = $this->get('session');
    $em = $this->getDoctrine()->getManager();

    $user = new User();

    $form = $this->createForm(new UserDeleteType(), $user);

    $form->handleRequest($request);

    if ($form->isValid()) 
    {
        $user = $form->getData();
        $exists = $em->getRepository('AppBundle:User')->findOneByEmail($user->getEmail());
        $loggedUser = $this->getUser();

        if(($exists && $exists==$loggedUser)) {
            return $this->redirect($this->generateUrl('menu_admin'));
        }
        if(!$exists){
            return $this->redirect($this->generateUrl('user_delete'));
        }
        foreach ($user->getRoles() as $role){
            $role->getUsers->removeElement($user);
            $em->persist($role);
        }

        $em->remove($user);
        $em->flush();
}

数据库中表格的结构:

| User  | CREATE TABLE `User` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `enabled` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_2DA17977F85E0677` (`username`),
  UNIQUE KEY `UNIQ_2DA17977E7927C74` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

| Role  | CREATE TABLE `Role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `role` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_F75B255457698A6A` (`role`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |


| user_role | CREATE TABLE `user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`role_id`),
  KEY `IDX_2DE8C6A3A76ED395` (`user_id`),
  KEY `IDX_2DE8C6A3D60322AC` (`role_id`),
  CONSTRAINT `FK_2DE8C6A3A76ED395` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON DELETE CASCADE,
  CONSTRAINT `FK_2DE8C6A3D60322AC` FOREIGN KEY (`role_id`) REFERENCES `Role` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

提前致谢!

1 个答案:

答案 0 :(得分:0)

首先,您尝试删除刚刚创建但未在任何地方保留的$user对象,而不是由实体管理器管理并找到的$exists对象。

其次,每次从中移除用户时都不应该持久$role,因此$role已经是托管实体,EntityManager已经知道了。

    foreach ($exists->getRoles() as $role){
        $role->getUsers->removeElement($exists);
    }

    $em->remove($exists);
    $em->flush();