Невозможно заставить работать ManyToOne ApiSubresource relaction. Ошибка: ожидается StateFieldPathExpression или SingleValuedAssociationField

Я начал делать небольшой проект на платформе API, чтобы проверить, как он работает.

К сожалению, в самом начале я столкнулся с проблемой, что я не могу установить связь @ApiSubresource ManyToOne, потому что это вызывает ошибку

«[Семантическая ошибка], строка 0, столбец 129 рядом с 'users =: cur': Ошибка: недопустимое выражение пути. Ожидается выражение StateFieldPathExpression или SingleValuedAssociationField.»

Мои классы выглядят так:

/**
 * @ApiResource(
 *     collectionOperations={"post"},
 *     itemOperations={
 *     "get"={ "security"="is_granted('VIEW_AS_OWNER_USER', object)", }
 *     },
 *     normalizationContext={"groups"={"operation:read"}},
 *     denormalizationContext={"groups"={"operation:write"}}
 * )
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @ORM\Table(name="`user`")
 */
class User implements UserInterface
{
    /* rest of the entity declaration omitted */
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Band", inversedBy="users")
     * @ApiSubresource()
     */
    private $band;
}
/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass="App\Repository\BandRepository")
 * @ORM\Table(name="band")
 */
class Band
{
    /* rest of the entity declaration omitted */

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="band")
     */
    private $users;

}

Покопавшись в Symfony Parser, похоже, что он пытается выполнить этот SQL:

ВЫБРАТЬ o FROM App \ Entity \ Band o ГДЕ o IN (ВЫБРАТЬ ИДЕНТИФИКАТОР (id_a1.band) FROM App \ Entity \ User id_a1 ГДЕ id_a1.id =: id_p1) И o.users =: current_user

С этими двумя параметрами:  введите описание изображения здесь

Я нашел несколько советов, но все они были для Symfony для ручного запроса. Существует некоторое автоматическое построение запросов, по крайней мере, для меня, на самом базовом уровне.

Вы знаете, что я сделал не так? Или это просто сломанный фреймворк?


person Dominik    schedule 26.04.2020    source источник
comment
Я проверил, все ли связано с идентификатором UUID, но нет, когда я меняю его на целое число, возникает то же исключение   -  person Dominik    schedule 26.04.2020
comment
Я также создал там отчет об ошибке: github.com/api-platform/api- platform / issues / 1513   -  person Dominik    schedule 26.04.2020
comment
Я начал проект с нуля и использую только идентификатор автоинкремента без UUID, и кажется, что он работает хорошо, но в любом случае это может быть проблемой для тех, кто хочет использовать UUID.   -  person Dominik    schedule 29.04.2020


Ответы (1)


Не рекомендуется использовать UUID в качестве первичного ключа. Все сравнения, выполняемые вашей базой данных, займут больше времени для сравнения строк, чем целые числа, поэтому соединения будут менее эффективными. У вас должно быть целое число в качестве первичного ключа. UUID используется, чтобы избежать попытки URL-адреса путем изменения идентификатора и тестирования всех идентификаторов. Затем вы можете просто использовать uuid как другое свойство. Вам нужно только установить для свойства Api identifier значение true, и API-платформа будет использовать его вместо первичного ключа. Этот совет, возможно, поможет решить вашу проблему, но я не уверен.

Думаю, вам следует подождать, пока команда API-платформы объединит этот запрос на вытягивание

Доктрина использует последовательность для создания автоинкремента. Таким образом, база данных никогда не будет пытаться вставить две записи с одинаковым ключом автоинкремента. Последовательность была создана, чтобы избежать этой проблемы.

UUID - небольшая проблема с производительностью, если вы добавляете индекс и ищете только свою сущность через этот uuid. Если вы сделаете что-то еще, например, внутреннее соединение с другим объектом, это будет большой проблемой для производительности.

person Alexandre Tranchant    schedule 26.04.2020
comment
Спасибо за ответ! А как насчет параллельного сохранения в базу данных? Используя автоинкремент, вы становитесь зависимым от реализации базы данных. Я слышал мнение (чтобы быть честным, я его не проверял), что в некоторых ситуациях база данных может попытаться вставить две записи с одинаковым ключом автоинкремента. Вот почему я решил полагаться на UUID. Это большая проблема с производительностью? - person Dominik; 27.04.2020
comment
Спасибо за ответ :) Сегодня я попробую сделать регулярное автоинкремент id и uuid для скрытия id от клиента. Поделюсь результатами, это исправит проблему. - person Dominik; 28.04.2020