在学说、symfony 中创建同一实体的两个实例之间的关系(外键指向其所在的表)

问题描述 投票:0回答:1

提前感谢您的所有回复 这是我在这里的第一条消息,所以请随时告诉我是否有一些我忘记向您提供的信息,以便确定问题的大小。

我有一个 symfony 项目(wamp 3.3.5 上的 symfony 6.1.12,php 8.2.18),我开始用学说(重新)创建我的数据库,我使用终端和学说的命令(php bin /控制台品牌:实体)

在两个不同实体之间创建关联/关系时一切都很好,但在尝试与同一实体的其他实例中的实体建立关系时则不然:进行迁移时,外键不会生成在数据库的物理表中。

我开始查看迁移文件,发现添加外键的查询没有生成,所以问题出在命令 make:entity 生成到 src/Entity 文件中的代码。我确信这应该是我的一些愚蠢的错误,做了一些测试(与ManyToOne创建OneToMany关系,手动编写代码等......)并尝试在网上寻找一些信息但没有成功(这很奇怪。 .. 指向自己表条目的外键不是原则上要做的事情吗?),但我不知道这里会出现什么问题。

例如,我第一次尝试创建一个可以有一个父实体并有多个子实体的实体。

这是我在终端中输入的内容:

C:\wamp64\www\symfony\le_capharnaum_mora>php bin/console make:entity

 Class name of the entity to create or update (e.g. TinyElephant):
 > entityTest

 created: src/Entity/EntityTest.php
 created: src/Repository/EntityTestRepository.php

In DoctrineHelper.php line 177:

  Attempted to load class "DisconnectedClassMetadataFactory" from namespace "Doctrine\ORM\Tools".
  Did you forget a "use" statement for another namespace?


make:entity [-a|--api-resource] [-b|--broadcast] [--regenerate] [--overwrite] [--] [<name>]


C:\wamp64\www\symfony\le_capharnaum_mora>php bin/console make:entity

 Class name of the entity to create or update (e.g. GentleChef):
 > entityTest

 Your entity already exists! So let's add some new fields!

 New property name (press <return> to stop adding fields):
 > name

 Field type (enter ? to see all types) [string]:
 >

 Field length [255]:
 >

 Can this field be null in the database (nullable) (yes/no) [no]:
 >

 updated: src/Entity/EntityTest.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > entityTestFather

 Field type (enter ? to see all types) [string]:
 > ManyToOne

 What class should this entity be related to?:
 > entityTest

 Is the EntityTest.entityTestFather property allowed to be null (nullable)? (yes/no) [yes]:
 >

 Do you want to add a new property to entityTest so that you can access/update EntityTest objects from it - e.g. $entityTest->getEntityTests()? (yes/no) [yes]:
 >

 A new property will also be added to the entityTest class so that you can access the related EntityTest objects from it.

 New field name inside entityTest [entityTests]:
 >

 updated: src/Entity/EntityTest.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 >



  Success!


 Next: When you're ready, create a migration with php bin/console make:migration


C:\wamp64\www\symfony\le_capharnaum_mora>php bin/console make:migration


 created: migrations/Version20240813111624.php


  Success!


 Review the new migration then run it with php bin/console doctrine:migrations:migrate
 See https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html

C:\wamp64\www\symfony\le_capharnaum_mora>php bin/console doctrine:migrations:migrate

 WARNING! You are about to execute a migration in database "lecafarnaummora" that could result in schema changes and data loss. Are you sure you wish to continue? (yes/no) [yes]:
 >

[notice] Migrating up to DoctrineMigrations\Version20240813111624
[notice] finished in 130.6ms, used 20M memory, 1 migrations executed, 3 sql queries

 [OK] Successfully migrated to version: DoctrineMigrations\Version20240813111624

这是 src/EntityTest.php

<?php

namespace App\Entity;

use App\Repository\EntityTestRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: EntityTestRepository::class)]
class EntityTest
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

    #[ORM\OneToMany(targetEntity: EntityTest::class, mappedBy: 'entityTestFather')]
    private Collection $entityTests;

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

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): static
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return Collection<int, EntityTest>
     */
    public function getEntityTests(): Collection
    {
        return $this->entityTests;
    }

    public function addEntityTest(EntityTest $entityTest): static
    {
        if (!$this->entityTests->contains($entityTest)) {
            $this->entityTests->add($entityTest);
            $entityTest->setEntityTestFather($this);
        }

        return $this;
    }

    public function removeEntityTest(EntityTest $entityTest): static
    {
        if ($this->entityTests->removeElement($entityTest)) {
            // set the owning side to null (unless already changed)
            if ($entityTest->getEntityTestFather() === $this) {
                $entityTest->setEntityTestFather(null);
            }
        }

        return $this;
    }
}

最后,这是迁移文件的代码,缺少关系的外键?

<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
 * Auto-generated Migration: Please modify to your needs!
 */
final class Version20240813111624 extends AbstractMigration
{
    public function getDescription(): string
    {
        return '';
    }

    public function up(Schema $schema): void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('CREATE TABLE base_de_donnees (id INT AUTO_INCREMENT NOT NULL, nom VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
        $this->addSql('CREATE TABLE entity_test (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
        $this->addSql('CREATE TABLE messenger_messages (id BIGINT AUTO_INCREMENT NOT NULL, body LONGTEXT NOT NULL, headers LONGTEXT NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL, available_at DATETIME NOT NULL, delivered_at DATETIME DEFAULT NULL, INDEX IDX_75EA56E0FB7336F0 (queue_name), INDEX IDX_75EA56E0E3BD61CE (available_at), INDEX IDX_75EA56E016BA31DB (delivered_at), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
    }

    public function down(Schema $schema): void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->addSql('DROP TABLE base_de_donnees');
        $this->addSql('DROP TABLE entity_test');
        $this->addSql('DROP TABLE messenger_messages');
    }
}
symfony terminal doctrine
1个回答
0
投票

您缺少父级的实际定义(我们可以在您的mappedBy属性中看到)。

你应该这样添加:

#[ORM\Entity(repositoryClass: EntityTestRepository::class)]
class EntityTest
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

    #[ORM\OneToMany(targetEntity: EntityTest::class, mappedBy: 'entityTestFather')]
    private Collection $entityTests;

    #[ORM\ManyToOne(targetEntity: EntityTest::class, inversedBy: 'entityTests')]
    private EntityTest $entityTestFather;

    // don't forget to add new public getters/setters
}
© www.soinside.com 2019 - 2024. All rights reserved.