Как устранить эту ошибку Столбец не найден?

Изначально сущность Gut имела поле reaction, содержащее строку. Варианты для reaction были встроены в шаблон. Добавив объект Reaction и изменив Gut формы reaction на EntityType, я теперь мучаюсь с сообщением об ошибке

SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.reaction' in 'field list'

хотя я переписал сущности Gut и Reaction. Наверное, я потерял из виду лес из-за деревьев. Что не так со следующим?

Таблица MySQL gut: столбец reaction заменен на reaction_id; reaction_id правильно создан; внешний ключ, созданный вручную.

Ошибка возникает с этим методом контроллера:

    #[Route('/', name: 'app_gut_index', methods: ['GET'])]
    public function index(GutRepository $gutRepository): Response
    {
        $guts = $gutRepository->findBy([], ['happened' => 'DESC']); // error thrown here
        
        return $this->render('gut/index.html.twig', [
                    'guts' => $guts,
        ]);
    }

Gut объект:


    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    #[ORM\ManyToOne(targetEntity: Reaction::class)]
    #[ORM\JoinColumn(name: 'reaction_id', referencedColumnName: 'id')]
    protected $reaction;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $description = null;

    #[ORM\Column(name: "datetime")]
    private ?\DateTime $happened = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getReaction(): ?Reaction
    {
        return $this->reaction;
    }

    public function setReaction(?Reaction $reaction): self
    {
        $this->reaction = $reaction;

        return $this;
    }
...
}

Reaction объект:


use App\Entity\Gut;
use App\Repository\ReactionRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

#[ORM\Entity(repositoryClass: ReactionRepository::class)]
class Reaction
{

    public function __construct()
    {
        $this->guts = new ArrayCollection();
    }

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 45)]
    private ?string $reaction = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getReaction(): ?string
    {
        return $this->reaction;
    }

    public function setReaction(string $reaction): self
    {
        $this->reaction = $reaction;

        return $this;
    }

    #[ORM\OneToMany(targetEntity: Gut::class, mappedBy: 'reaction')]
    private $guts;

    /**
     * @return Collection|Product[]
     */
    public function getGuts(): Collection
    {
        return $this->guts;
    }

    public function addGut($gut): self
    {
        $this->guts[] = $gut;

        return $this;
    }

    public function __toString()
    {
        return $this->getReaction();
    }

}

Итак, bin/console doctrine:schema:update --dump-sql показывает, что все синхронизировано? Можете показать код формы для ->add('reaction',...? И, конечно же, вы очистили кеш.

Cerad 29.12.2022 14:23

Ваша схема базы данных не синхронизирована с вашими объектами. В частности, у одного из ваших объектов есть поле, которого на самом деле нет в базе данных. Может быть, вы забыли запустить и/или сгенерировать миграцию?

nacholibre 29.12.2022 14:47

Схема определенно не синхронизирована. Обновление заменило gut.reaction_id на ...reaction. После обновления столбец gut.reaction пуст, но восстановлен из резервной копии. Ошибка сейчас getReaction(): Return value must be of type ?App\Entity\Reaction, string returned. add() отсутствует.

geoB 29.12.2022 15:37

Что меня смущает, так это то, что я ожидал, что ManyToOne создаст оператор SQL с JOIN в нем. Нравится select g.id, r.reaction, g.description, g.datetime` из кишки g присоединиться к реакции r на r.id = g.reaction порядок по g.datetime asc. Instead, the log shows SELECT t0.id КАК id_1, t0.реакция КАК реакция_2, t0.описание КАК description_3, t0.datetime КАК datetime_4 FROM t0 ORDER BY t0.datetime DESC`.

geoB 29.12.2022 19:10

Ради интереса создайте новую базу данных и запустите доктрину: схема: создать, просто чтобы посмотреть, что вы получите, начав с чистого листа. Может поможет сузить тему. Вы правы, имя столбца базы данных должно быть response_id.

Cerad 29.12.2022 19:15

Спасибо за мысль. Я на самом деле попробовал ваше предложение и в итоге не нашел, где. Поскольку это внутренний семейный проект, я просто вернусь к запрограммированным реакциям. Рад, что у меня есть серия коммитов git, которые нужно отменить.

geoB 29.12.2022 19:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
6
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш ресурс $reaction не должен иметь аннотаций ORM\Column и ORM\JoinColumn одновременно.

Из-за этого Doctrine считает, что это обычный столбец, поэтому ищет поле базы данных на основе имени переменной: $reaction -> gut.reaction.

Удалите #[ORM\Column(length: 255)], затем убедитесь, что gut.reaction_id есть в вашей базе данных, и теперь это должно работать.

В качестве небольшого примечания, я не думаю, что вам нужно name: 'reaction_id', referencedColumnName: 'id' в ORM\JoinColumn, потому что Doctrine все равно назовет их автоматически.

Ответ принят как подходящий

Просто не мог отпустить. В конце концов я нашел способ заставить сущности Кишки и Реакции хорошо играть вместе. Что я сделал:

  • клонировал проект
  • вручную удалено свойство реакции из объекта Gut; создал и выполнил миграцию
  • в MySQL, добавлено обратно в столбец реакции
  • использовал make:entity Gut, чтобы добавить свойство реакции как ManyToOne на реакцию; сделал миграцию
  • использовал MySQL для заполнения столбца response_id из базы данных клонированного проекта.
  • (Возможно, где-то здесь пропущен шаг, но) gut->getReaction() и т. д. теперь ведут себя так, как ожидалось - в отношении ManyToOne.

Другие вопросы по теме