我有一个User实体。这些用户可以成为朋友。所以我定义了一个自我引用的manymany单向关联(因为总是有互惠是友谊,对吧?)
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]: Integrity constraint violation: 1062
当我检查日志时,我可以看到doctrine试图执行相同的插入查询两次。
我的addFriendList
函数
public function addFriendList(User $friend)
{
if (!$this->friendList->contains($friend)) {
$this->friendList[] = $friend;
$friend->addFriendList($this);
}
}
我哪里错了
我终于找到了解决问题的办法。然而,我仍然不知道这是一个Doctrine2的缺陷,或者它是否按照设计工作。
我需要在添加好友之前持久化我的用户和刷新。
所以我的工作代码是:$em->persist($user);
$em-flush();
$user->addFriendList($friend);
$em->persist($user);
$em->flush();
@Reuven,你写道:
$this->friendList[] = $friend;
$friend->addFriendList($this);
好吧,你插入了两次关系。
这应该足够了:
$this->friendList[] = $friend;
这是因为您没有指定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;
}