I use a one-to-one relationship as an id for an entity:
Actor entity
$metadata->mapOneToOne([
'fieldName' => 'user',
'id' => true,
'targetEntity' => AbstractUser::class,
'inversedBy' => 'actor',
'cascade' => ['all'],
'joinColumns' => [
[
'name' => 'user_id',
'referencedColumnName' => 'id',
'nullable' => false,
]
],
]);
and the other side:
AbstractUser entity
$metadata->mapField([
'fieldName' => 'id',
'type' => 'string',
'length' => 36,
'id' => true,
'strategy' => 'none',
'unique' => true,
]);
$metadata->mapOneToOne([
'fieldName' => 'actor',
'targetEntity' => Actor::class,
'mappedBy' => 'user',
'cascade' => ['all'],
]);
Then I have a third entity (Subscription) referencing the Actor entity:
$metadata->mapManyToOne([
'fieldName' => 'subscribingActor',
'targetEntity' => Actor::class,
'joinColumns' => [
[
'name' => 'subscribing_actor_id',
'referencedColumnName' => 'user_id',
'nullable' => false,
],
],
]);
The query I try to run looks like this:
function findByActors(Actor $subscribingActor, Actor $subscribedActor): ?Subscription
{
$qb = $this->entityRepository->createQueryBuilder('s');
$qb
->where('s.subscribingActor = :subscribingActor')
->setParameter('subscribingActor', $subscribingActor);
return $qb->getQuery()->getOneOrNullResult();
}
This results in the following exception:
Object of InternalUser (extends AbstractUser) could not be converted to string
If I implement AbstractUser::__toString() returning the id of the user everything works fine.
The strange thing: if I load the entity freshly from the database, it works. If I create it, persist it and use that every entity object I get the above "to string" error.
My question is now, why is doctrine not able to detect the id value through the mapOneToOne -> joinColumns[0]['referencedColumnName'] information but instead does try to call __toString() on the related object although it's clear from the mapping where it could find the PK value of the related entity but only if the entity is not initially loaded from the database?