Doctrine: User class object cannot be converted to a string

I keep getting this error with 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 

On my system, users can have many permissions in a single to large relationship. I created a User object and Permission . They look like this (I removed some annotations, getters and setters to reduce clutter):

 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; } } 

The problem occurs when I add a new Permission to User :

 $permission = new Permission(); $user->getPermissions()->add( $permission ); $em->persist( $user ); $em->flush(); 

This is the last bit of my stack trace:

 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 

Any understanding would be greatly appreciated.

+6
source share
4 answers

Your decision made me understand what was going on.

Even if you have entities and annotations, the Doctrine cannot understand the connection between entities. When the doctrine understands the relationship between entities, it knows which methods to call (i.e., User :: getId ()), but otherwise it tries to convert everything you send into a scalar value that it can use to query the database . This is why it calls the __toString function of the user, and therefore, if you return the identifier in toString, everything works from here.

That's fine, but it's a patch, and you probably don't want to store it if we can find a better solution, as it can be harder to maintain as your application grows.

What I see is what in Permissions you have:

 /** * @ORM\Column(name="user_id", type="integer") * @ORM\ManyToOne(targetEntity="User", inversedBy="permissions") */ protected $user; 

You must remove @ORM\Column(type="integer" )

About join columns, this is optional, but you need to be sure that defauts is what you want. Since we can read here

Before entering all association mappings in detail, you should note that the definitions of @JoinColumn and @JoinTable are usually optional and have reasonable default values. By default, for joining a column in a one-to-one / many-one association:

 name: "<fieldname>_id" referencedColumnName: "id" 

therefore they will be the same as explicit:

 /** * @ORM\ManyToOne(targetEntity="User", inversedBy="permissions", cascade={"persist"}) * @ORM\JoinColumns({ * @ORM\JoinColumn(name="user_id", referencedColumnName="id") * }) */ protected $user; 

Thus, it should look up the user_id column in the Permissions table and join it with the id column of the User table. Suppose this is normal.

If this is true, then in your user the identifier should be user_id, but id:

  /** * @ORM\Column(name="id", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ protected $id; 

Or, if the column name is actually user_id, then the User class is fine, but you need to change the join column to @ORM \ JoinColumn (name = "user_id", referencedColumnName = "user_id")

What can I say. I can’t try, but I will be glad if you can give him a second.

+7
source

OK It works for me.

I have not yet fully determined the reason, but when I add the following to my User object, it works:

 class User { public function __toString() { return strval( $this->getId() ); } } 

If I find out more, I will post here.

+8
source

I think there is a problem with displaying a user property in a resolving entity. Try the following:

 /** * @ORM\ManyToOne(targetEntity="User", inversedBy="permissions") * @JoinColumn(name="user_id", referencedColumnName="id") */ protected $user; 
+3
source

Are you initializing the collection on the OneToMany side? as well as methods to add and remove from the collection?

 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); } //... 
0
source

All Articles