Luk*_*uke 6 php entity-relationship doctrine-orm
我一直在用Doctrine得到这个错误:
PHP Catchable fatal error: Object of class User could not be converted to string in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 1337
Run Code Online (Sandbox Code Playgroud)
在我的系统中,用户可以在一对多关系中拥有许多权限.我已经建立了一个User与Permission实体.它们看起来像这样(我删除了一些注释,getter和setter以减少混乱):
class User {
/**
* @ORM\Column(name="user_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
public function getId()
{
return $this->id;
}
/**
* @ORM\OneToMany(targetEntity="Permission", mappedBy="user", cascade={"persist"})
*/
protected $permissions;
public function getPermissions()
{
return $this->permissions;
}
}
class Permission {
/**
* @ORM\Column(name="user_id", type="integer")
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions")
*/
protected $user;
public function getUser()
{
return $this->user;
}
public function setUser( $user )
{
$this->user = $user;
return $this;
}
}
Run Code Online (Sandbox Code Playgroud)
当我添加一个新出现该问题Permission的User:
$permission = new Permission();
$user->getPermissions()->add( $permission );
$em->persist( $user );
$em->flush();
Run Code Online (Sandbox Code Playgroud)
这是我的堆栈跟踪的最后一点:
PHP 11. Doctrine\ORM\UnitOfWork->persist() vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:565
PHP 12. Doctrine\ORM\UnitOfWork->doPersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1555
PHP 13. Doctrine\ORM\UnitOfWork->cascadePersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1615
PHP 14. Doctrine\ORM\UnitOfWork->doPersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2169
PHP 15. Doctrine\ORM\UnitOfWork->persistNew() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1597
PHP 16. Doctrine\ORM\UnitOfWork->scheduleForInsert() doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:836
PHP 17. Doctrine\ORM\UnitOfWork->addToIdentityMap() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1157
PHP 18. implode() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1337
Run Code Online (Sandbox Code Playgroud)
任何见解将不胜感激.
好.我有它的工作.
我还没有完全弄清楚原因,但当我将以下内容添加到我的User实体时,它可以工作:
class User {
public function __toString()
{
return strval( $this->getId() );
}
}
Run Code Online (Sandbox Code Playgroud)
如果我发现更多,我会在这里发布.
你的解决方案给了我一些发生了什么的线索.
即使你有实体和anotations,Doctrine也无法理解实体之间的关系.当学说理解实体之间的关系时,它知道要调用哪些方法(即User :: getId()),否则,它会尝试将您发送的任何内容转换为可用于查询数据库的标量值.这就是为什么它调用User的__toString函数,这就是为什么如果你在toString中返回id,一切都可以在这里工作.
这是好的,但它是一个补丁,如果我们能找到更好的解决方案,你可能不想保留它,因为随着应用程序的增长,它可能更难维护.
我能看到的是,在您拥有的权限中:
/**
* @ORM\Column(name="user_id", type="integer")
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions")
*/
protected $user;
Run Code Online (Sandbox Code Playgroud)
你应该删除@ORM\Column(type="integer")
关于连接列,它不是强制性的,但你必须确保你想要的是defauts.我们可以在这里阅读
在我们详细介绍所有关联映射之前,您应该注意@JoinColumn和@JoinTable定义通常是可选的,并且具有合理的默认值.一对一/多对一关联中的连接列的默认值如下:
name: "<fieldname>_id"
referencedColumnName: "id"
Run Code Online (Sandbox Code Playgroud)
所以,他们将是明确的:
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions", cascade={"persist"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
protected $user;
Run Code Online (Sandbox Code Playgroud)
因此,它应该user_id在Permissions表中查找列,并将其与表的id列连接User.我们认为这没关系.
如果这是真的,那么在你的用户中,id不应该是user_id,而是id:
/**
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
Run Code Online (Sandbox Code Playgroud)
或者,如果列名实际上是user_id,则User类没问题,但您必须将join列更改为@ORM\JoinColumn(name ="user_id",referencedColumnName ="user_id")
我可以这么说.我不能尝试知道,但如果你能给它一秒钟,我会很高兴的.