Доктрина: объект класса User не может быть преобразован в строку
Я продолжаю получать эту ошибку с доктриной:
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
в моей системе пользователи могут иметь много разрешений в отношениях один ко многим. Я установил User
и Permission
сущности. Они выглядят так (я удалил некоторые аннотации, геттеры и сеттеры, чтобы уменьшить беспорядок):
class User {
/**
* @ORMColumn(name="user_id", type="integer", nullable=false)
* @ORMId
* @ORMGeneratedValue(strategy="IDENTITY")
*/
protected $id;
public function getId()
{
return $this->id;
}
/**
* @ORMOneToMany(targetEntity="Permission", mappedBy="user", cascade={"persist"})
*/
protected $permissions;
public function getPermissions()
{
return $this->permissions;
}
}
class Permission {
/**
* @ORMColumn(name="user_id", type="integer")
* @ORMManyToOne(targetEntity="User", inversedBy="permissions")
*/
protected $user;
public function getUser()
{
return $this->user;
}
public function setUser( $user )
{
$this->user = $user;
return $this;
}
}
проблема возникает, когда я Добавить новый Permission
до User
:
$permission = new Permission();
$user->getPermissions()->add( $permission );
$em->persist( $user );
$em->flush();
это последний бит моей трассировки стека:
PHP 11. DoctrineORMUnitOfWork->persist() vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:565
PHP 12. DoctrineORMUnitOfWork->doPersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1555
PHP 13. DoctrineORMUnitOfWork->cascadePersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1615
PHP 14. DoctrineORMUnitOfWork->doPersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2169
PHP 15. DoctrineORMUnitOfWork->persistNew() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1597
PHP 16. DoctrineORMUnitOfWork->scheduleForInsert() doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:836
PHP 17. DoctrineORMUnitOfWork->addToIdentityMap() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1157
PHP 18. implode() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1337
любое понимание было бы очень признателен.
4 ответов
ваше решение дало мне ключ к пониманию того, что происходит.
даже если у вас есть сущности и анотации, доктрина не в состоянии понять отношения между сущностями. Когда doctrine понимает связь между сущностями, он знает, какие методы вызывать (например, User::getId ()), но в противном случае он пытается преобразовать все, что вы отправляете, в скалярное значение, которое он может использовать для запроса базы данных. Вот почему он вызывает функцию __toString пользователя и вот почему, если вы возвращаете идентификатор в toString, все работает отсюда.
это нормально, но это патч, и, вероятно, вы не хотите держать его, если мы сможем найти лучшее решение, так как это может быть сложнее поддерживать по мере роста вашего приложения.
что я вижу, это то, что в разрешениях у вас есть:
/**
* @ORM\Column(name="user_id", type="integer")
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions")
*/
protected $user;
вы должны удалить @ORM\Column(type="integer"
)
о соединения колонок, это не является обязательным, но вы должны быть уверены, что defauts, являются что ты хочешь. Как мы можем читать здесь
прежде чем мы представим все сопоставления ассоциаций подробно, вы должны обратите внимание, что определения @JoinColumn и @JoinTable обычно необязательно и имеют разумные значения по умолчанию. По умолчанию для соединения столбец в ассоциации "один к одному" / "много к одному" выглядит следующим образом:
name: "<fieldname>_id"
referencedColumnName: "id"
Итак, они будут такими же, как явное:
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions", cascade={"persist"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
protected $user;
таким образом, он должен искать колонка user_id
на Permissions
таблица, и присоединиться к нему с на User
таблица. Мы полагаем, что это нормально.
если это правда, то в вашем пользователе id не должен быть user_id, но id:
/**
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
или если имя столбца на самом деле user_id, то класс пользователя в порядке, но вы должны изменить столбец соединения на @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
что я могу сказать. Я не могу попробовать, знаю, но я буду. рад, если вы можете дать ему вторую.
OK. У меня все работает.
Я еще не полностью разработал причину, но когда я добавляю следующее К моему User
организация работ:
class User {
public function __toString()
{
return strval( $this->getId() );
}
}
Если я узнаю больше, я опубликую здесь.
Я думаю, что есть проблема с отображением свойств пользователя в сущности разрешение. Попробуйте вот это:
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions")
* @JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
вы инициализируете коллекцию на своей стороне OneToMany? а также методы для добавления и удаления из коллекции?
class User {
/**
* @ORM\OneToMany(targetEntity="Permission", mappedBy="user", cascade={"persist"})
*/
protected $permissions;
public function getPermissions()
{
return $this->permissions;
}
public function __construct()
{
$this->permissions = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addPermissions (Permission $permissions)
{
$this->permissions[] = $permissions;
return $this;
}
public function removePermissions(Permission $permissions)
{
$this->permissions->removeElement($permissions);
}
//...