DQL无法通过一对一关系解析主键作为参数

DQL cannot resolve primary key through one-to-one relationship as parameter

我使用一对一关系作为实体的 ID:

演员实体

$metadata->mapOneToOne([
    'fieldName' => 'user',
    'id' => true,
    'targetEntity' => AbstractUser::class,
    'inversedBy' => 'actor',
    'cascade' => ['all'],
    'joinColumns' => [
        [
            'name' => 'user_id',
            'referencedColumnName' => 'id',
            'nullable' => false,
        ]
    ],
]);

另一边:

抽象用户实体

$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'],
]);

然后我有第三个实体 (Subscription) 引用 Actor 实体:

$metadata->mapManyToOne([
    'fieldName' => 'subscribingActor',
    'targetEntity' => Actor::class,
    'joinColumns' => [
        [
            'name' => 'subscribing_actor_id',
            'referencedColumnName' => 'user_id',
            'nullable' => false,
        ],
    ],
]);

我尝试 运行 的查询如下所示:

function findByActors(Actor $subscribingActor, Actor $subscribedActor): ?Subscription
{
    $qb = $this->entityRepository->createQueryBuilder('s');
    $qb
        ->where('s.subscribingActor = :subscribingActor')
        ->setParameter('subscribingActor', $subscribingActor);

    return $qb->getQuery()->getOneOrNullResult();
}

这会导致以下异常:

Object of InternalUser (extends AbstractUser) could not be converted to string

如果我实现 AbstractUser::__toString() 返回用户的 id,一切正常。

奇怪的事情: 如果我从数据库中重新加载实体,它就可以工作。如果我创建它,坚持它并使用我得到上述 "to string" 错误的每个实体对象。

我现在的问题是,为什么 doctrine 无法通过 mapOneToOne -> joinColumns[0]['referencedColumnName'] 信息检测到 id 值,而是尝试在相关对象上调用 __toString()虽然从映射中可以清楚地看出它可以在哪里找到相关实体的 PK 值,但前提是该实体最初不是从数据库加载的?

你可以测试这个:

    function findByActors(Actor $subscribingActor): ?Subscription
    {
        $qb = $this->entityRepository->createQueryBuilder('s');
        $qb->leftJoin('s.subscribingActor', 'subscribingActor')
            ->where('subscribingActor.id = :subscribingActorId')
            ->setParameter('subscribingActorId', $subscribingActor->getId());

        return $qb->getQuery()->getOneOrNullResult();
    }

希望对您有所帮助

不知何故,学说无法通过映射确定Actor实体的PK。提供原始实体User有助于学说解决一切:

function findByActors(Actor $subscribingActor, Actor $subscribedActor): ?Subscription
{
    $qb = $this->entityRepository->createQueryBuilder('s');
    $qb
        ->where('s.subscribingActor = :subscribingActor')
        ->setParameter('subscribingActor', $subscribingActor->getUser());
        // or $subscribingActor->getUser()->getId() to be even more explicit

    return $qb->getQuery()->getOneOrNullResult();
}