Doctrine2 关系(多对多)在 ZF3 中不起作用
Doctrine2 Relationships (ManyToMany) not working in ZF3
我花了 2 天时间解决这个问题,但我仍然找不到它不起作用的解决方案。
我使用 this tutorial to implement Doctrine in Zend Framework 3. On this 站点是实体中 ManyToMany 关系的实现。我在我的项目(用户角色)中使用了它 1:1 但它不起作用。每次我想为用户 ($user->getRoles()) 获取所有角色时,我都会得到 NULL
用户实体
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM;
use Development\Entity\AbstractEntity;
use Development\Entity\Traits\EntityId;
use Development\Exception\EntityException;
use Doctrine\Common\Collections\ArrayCollection;
use Utils\StringUtils;
/**
* @ORM\Entity(repositoryClass="User\Repository\UserRepository")
* @ORM\Table(name="user")
*/
class User extends AbstractEntity
{
use EntityId;
/**
* @ORM\Column(name="name")
*/
protected $name;
/**
* @ORM\Column(name="surname")
*/
protected $surname;
/**
* @ORM\Column(name="position")
*/
protected $position;
/**
* @ORM\Column(name="phone")
*/
protected $phone;
/**
* @ORM\Column(name="login")
*/
protected $login;
/**
* @ORM\Column(name="password")
*/
protected $password;
/**
* @ORM\ManyToMany(targetEntity="User\Entity\Role")
* @ORM\JoinTable(name="user_role",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
private $roles;
public function __construct()
{
$this->roles = new ArrayCollection();
}
public function __toString()
{
return $this->getFullName();
}
public function addRole($role)
{
$this->roles[] = $role;
}
public function getRoles()
{
return $this->roles;
}
public function removeRole($role)
{
$this->roles->removeElement($role);
}
/**
* @param integer $mbCase
*
* @return string
*
*/
public function getFullName($mbCase = MB_CASE_TITLE)
{
if (!StringUtils::isEmpty($this->surname)) {
$fullName = mb_convert_case($this->name . ' ' . $this->surname, $mbCase, "UTF-8");
} else {
$fullName = mb_convert_case($this->name, $mbCase, "UTF-8");
}
return trim($fullName);
}
/**
* @return string
*
*/
public function getLogin()
{
return $this->login;
}
/**
* @return string
*
*/
public function getPassword()
{
return $this->password;
}
/**
* @param mixed $login
*/
public function setLogin($login)
{
$this->login = StringUtils::toLower($login);
}
}
角色实体
<?php
namespace User\Entity;
use Development\Entity\AbstractEntity;
use Development\Entity\Traits\EntityId;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* This class represents a role.
* @ORM\Entity()
* @ORM\Table(name="role")
*/
class Role extends AbstractEntity
{
use EntityId;
/**
* @ORM\Column(name="name")
*/
protected $name;
/**
* @ORM\Column(name="description")
*/
protected $description;
/**
* @ORM\Column(name="date_created")
*/
protected $dateCreated;
/**
* @var Role[]
*
* @ORM\ManyToMany(targetEntity="User\Entity\Role")
* @ORM\JoinTable(name="role_hierarchy",
* joinColumns={@ORM\JoinColumn(name="child_role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="parent_role_id", referencedColumnName="id")}
* )
*/
private $parentRoles;
/**
* @var Role[]
*
* @ORM\ManyToMany(targetEntity="User\Entity\Role")
* @ORM\JoinTable(name="role_hierarchy",
* joinColumns={@ORM\JoinColumn(name="parent_role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="child_role_id", referencedColumnName="id")}
* )
*/
protected $childRoles;
/**
* @var Permission[]
*
* @ORM\ManyToMany(targetEntity="User\Entity\Permission")
* @ORM\JoinTable(name="role_permission",
* joinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
* )
*/
private $permissions;
/**
* Constructor.
*/
public function __construct()
{
$this->parentRoles = new ArrayCollection();
$this->childRoles = new ArrayCollection();
$this->permissions = new ArrayCollection();
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
}
public function getDateCreated()
{
return $this->dateCreated;
}
public function setDateCreated($dateCreated)
{
$this->dateCreated = $dateCreated;
}
public function getParentRoles()
{
return $this->parentRoles;
}
public function getChildRoles()
{
return $this->childRoles;
}
public function getPermissions()
{
return $this->permissions;
}
}
我正在使用最新的 Doctrine ORM 模块和 Zend3。
你知道我应该在哪里寻找解决方案吗?如果需要,我将在接下来的 8 小时内添加代码。
在这种教义关系中,什么是重要的?其他关系正常。
您确定针对数据库中的用户保存了角色吗?我会先检查一下。
这可能有帮助:Symfony2-Doctrine: ManyToMany relation is not saved to database
我试过你的例子,它对我有用。一些你必须考虑的事情。
在 Doctrine 中,关联默认被标记为 Lazy,这意味着关联的整个集合对象在第一次访问时被填充。因此,为了填充您的角色,您必须执行以下操作:
foreach ($user->getRoles() as $role) {
echo $role->getName();
}
或者,您可以在关联注释中使用 fetch="EAGER"
:
/**
* @ORM\ManyToMany(targetEntity="User\Entity\Role", fetch="EAGER")
* @ORM\JoinTable(name="user_role",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
private $roles;
查看此 question 以了解 fetch="EAGER"
和 fetch="LAZY"
之间的区别
您确定角色实体是否正确:当我使用时:
./vendor/bin/doctrine-module orm:validate-schema
我收到以下错误
Mapping
-------
[OK] The mapping files are correct.
Database
--------
In SchemaException.php line 112:
The table with name 'bmv5.role_hierarchy' already exists.
当我尝试 orm:schema-tool:update --force
时也是如此
我花了 2 天时间解决这个问题,但我仍然找不到它不起作用的解决方案。 我使用 this tutorial to implement Doctrine in Zend Framework 3. On this 站点是实体中 ManyToMany 关系的实现。我在我的项目(用户角色)中使用了它 1:1 但它不起作用。每次我想为用户 ($user->getRoles()) 获取所有角色时,我都会得到 NULL
用户实体
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM;
use Development\Entity\AbstractEntity;
use Development\Entity\Traits\EntityId;
use Development\Exception\EntityException;
use Doctrine\Common\Collections\ArrayCollection;
use Utils\StringUtils;
/**
* @ORM\Entity(repositoryClass="User\Repository\UserRepository")
* @ORM\Table(name="user")
*/
class User extends AbstractEntity
{
use EntityId;
/**
* @ORM\Column(name="name")
*/
protected $name;
/**
* @ORM\Column(name="surname")
*/
protected $surname;
/**
* @ORM\Column(name="position")
*/
protected $position;
/**
* @ORM\Column(name="phone")
*/
protected $phone;
/**
* @ORM\Column(name="login")
*/
protected $login;
/**
* @ORM\Column(name="password")
*/
protected $password;
/**
* @ORM\ManyToMany(targetEntity="User\Entity\Role")
* @ORM\JoinTable(name="user_role",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
private $roles;
public function __construct()
{
$this->roles = new ArrayCollection();
}
public function __toString()
{
return $this->getFullName();
}
public function addRole($role)
{
$this->roles[] = $role;
}
public function getRoles()
{
return $this->roles;
}
public function removeRole($role)
{
$this->roles->removeElement($role);
}
/**
* @param integer $mbCase
*
* @return string
*
*/
public function getFullName($mbCase = MB_CASE_TITLE)
{
if (!StringUtils::isEmpty($this->surname)) {
$fullName = mb_convert_case($this->name . ' ' . $this->surname, $mbCase, "UTF-8");
} else {
$fullName = mb_convert_case($this->name, $mbCase, "UTF-8");
}
return trim($fullName);
}
/**
* @return string
*
*/
public function getLogin()
{
return $this->login;
}
/**
* @return string
*
*/
public function getPassword()
{
return $this->password;
}
/**
* @param mixed $login
*/
public function setLogin($login)
{
$this->login = StringUtils::toLower($login);
}
}
角色实体
<?php
namespace User\Entity;
use Development\Entity\AbstractEntity;
use Development\Entity\Traits\EntityId;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* This class represents a role.
* @ORM\Entity()
* @ORM\Table(name="role")
*/
class Role extends AbstractEntity
{
use EntityId;
/**
* @ORM\Column(name="name")
*/
protected $name;
/**
* @ORM\Column(name="description")
*/
protected $description;
/**
* @ORM\Column(name="date_created")
*/
protected $dateCreated;
/**
* @var Role[]
*
* @ORM\ManyToMany(targetEntity="User\Entity\Role")
* @ORM\JoinTable(name="role_hierarchy",
* joinColumns={@ORM\JoinColumn(name="child_role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="parent_role_id", referencedColumnName="id")}
* )
*/
private $parentRoles;
/**
* @var Role[]
*
* @ORM\ManyToMany(targetEntity="User\Entity\Role")
* @ORM\JoinTable(name="role_hierarchy",
* joinColumns={@ORM\JoinColumn(name="parent_role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="child_role_id", referencedColumnName="id")}
* )
*/
protected $childRoles;
/**
* @var Permission[]
*
* @ORM\ManyToMany(targetEntity="User\Entity\Permission")
* @ORM\JoinTable(name="role_permission",
* joinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
* )
*/
private $permissions;
/**
* Constructor.
*/
public function __construct()
{
$this->parentRoles = new ArrayCollection();
$this->childRoles = new ArrayCollection();
$this->permissions = new ArrayCollection();
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
}
public function getDateCreated()
{
return $this->dateCreated;
}
public function setDateCreated($dateCreated)
{
$this->dateCreated = $dateCreated;
}
public function getParentRoles()
{
return $this->parentRoles;
}
public function getChildRoles()
{
return $this->childRoles;
}
public function getPermissions()
{
return $this->permissions;
}
}
我正在使用最新的 Doctrine ORM 模块和 Zend3。 你知道我应该在哪里寻找解决方案吗?如果需要,我将在接下来的 8 小时内添加代码。 在这种教义关系中,什么是重要的?其他关系正常。
您确定针对数据库中的用户保存了角色吗?我会先检查一下。
这可能有帮助:Symfony2-Doctrine: ManyToMany relation is not saved to database
我试过你的例子,它对我有用。一些你必须考虑的事情。 在 Doctrine 中,关联默认被标记为 Lazy,这意味着关联的整个集合对象在第一次访问时被填充。因此,为了填充您的角色,您必须执行以下操作:
foreach ($user->getRoles() as $role) {
echo $role->getName();
}
或者,您可以在关联注释中使用 fetch="EAGER"
:
/**
* @ORM\ManyToMany(targetEntity="User\Entity\Role", fetch="EAGER")
* @ORM\JoinTable(name="user_role",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
private $roles;
查看此 question 以了解 fetch="EAGER"
和 fetch="LAZY"
您确定角色实体是否正确:当我使用时:
./vendor/bin/doctrine-module orm:validate-schema
我收到以下错误
Mapping
-------
[OK] The mapping files are correct.
Database
--------
In SchemaException.php line 112:
The table with name 'bmv5.role_hierarchy' already exists.
当我尝试 orm:schema-tool:update --force
时也是如此