DQL не может разрешить первичный ключ через отношение один-к-одному в качестве параметра - PullRequest
5 голосов
/ 11 апреля 2020

Я использую отношение один-к-одному в качестве идентификатора для сущности:

Актер сущности

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

, а другая сторона:

сущность AbstractUser

$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();
}

Это приводит к следующему исключению:

Объект InternalUser (extends AbstractUser) невозможно преобразовать в строку

Если я реализую AbstractUser::__toString(), возвращая идентификатор пользователя, все работает нормально.

Странная вещь: , если я загружаю сущность только что из базы данных, она работает. Если я создаю его, сохраняю его и использую для каждого объекта сущности, который я получаю вышеупомянутую ошибку «to string».

Мой вопрос сейчас, почему doctrine не может обнаружить значение идентификатора через mapOneToOne -> joinColumns[0]['referencedColumnName'] информация, но вместо этого он пытается вызвать __toString() для связанного объекта, хотя из сопоставления ясно, где он может найти значение PK связанного объекта, но только если объект изначально не загружен из базы данных?

Ответы [ 2 ]

2 голосов
/ 18 апреля 2020

Почему-то doctrine просто не может определить PK объекта Actor посредством сопоставления. Предоставление исходной сущности User помогает doctrine разрешить все:

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();
}
0 голосов
/ 16 апреля 2020

Вы можете проверить это:

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

Надеюсь, эта помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...