【问题标题】:Doctrine - Symfony2 | Many to Many targeting the same entity教义- Symfony2 |多对多针对同一实体
【发布时间】:2014-08-15 17:16:53
【问题描述】:

我正在尝试创建一个针对同一实体的多对多外键表关系。

我已成功创建与其他实体的关系,但在定位同一实体时遇到问题。

我阅读了一些堆栈溢出问题和答案,并看到我正在做的事情是可能的.. I based my class of this example - 当我添加父级时,表unit_relations 为空,但当我将子级添加到单元时有效。我假设是因为该字段具有 inversedBy 注释。

我需要添加什么来允许双向更新/插入?

I tried swapping the joinColums like this answer - 没什么...

--

 /**
 * Unit
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Acme\DemoBundle\Entity\UnitRepository")
 */
class Unit
{
   ....

   /**
     * @ORM\ManyToMany(targetEntity="Unit",  inversedBy="parents")
     * @ORM\JoinTable(name="unit_relations",
     *     joinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="child_unit_id", referencedColumnName="id")}
     * )
     */
    private $children;

    /**
     * @ORM\ManyToMany(targetEntity="Unit",  mappedBy="children")
     */
    private $parents;
}

添加inversedBy而不是mappedBy,同时连接列也交换了,正确的做法是什么?

谁能解释一下?

/**
     * @ORM\ManyToMany(targetEntity="Unit",  inversedBy="parents")
     * @ORM\JoinTable(name="unit_relations",
     *     joinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="child_unit_id", referencedColumnName="id")}
     * )
     */
    private $children;

    /**
     * @ORM\ManyToMany(targetEntity="Unit",  inversedBy="children")
     * @ORM\JoinTable(name="unit_relations",
     *     joinColumns={@ORM\JoinColumn(name="child_unit_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")}
     * )
     */
    private $parents;

编辑

根据要求,这里是显示我如何创建关系的代码。我刚刚意识到这可能是因为实体还没有 id,因为我在其创建时添加了关系...

$unit = new \Acme\DemoBundle\Entity\Unit();
/* @var $parentUnit \Acme\DemoBundle\Entity\Unit */
$parentUnit = $this->getDoctrine()->getRepository('AcmeDemoBundle:Unit')->findById($request->get('unitId'));
$unit->addParent($parentUnit);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($unit);
$entityManager->flush();

【问题讨论】:

  • 究竟是什么问题/错误?
  • @RoToRa 我的第一个 sn-p 仅允许您将一个单元添加到关系中,如果您将其添加为子关系。如果将其添加为父级,则不会更新联接表。所以我发现了我的第二个sn-p;通过将mappedBy 更改为inversedBy 它可以双向工作,但它似乎不是“正确”的方式。我正在寻求澄清它为什么起作用,或者我是否缺少合适的替代方案
  • 你能显示你使用的代码添加一个单位到关系中(作为孩子和父母)?
  • @RoToRa 我已经添加了代码,但我开始怀疑它是否是因为实体还没有被持久化并刷新到数据库所以它还没有 ID。 .
  • 是的,这是一个很好的假设。添加孩子时是否使用相同的代码?无论如何,请先尝试持久化并刷新新单元。您还记得在实体构造函数中为 $children$parent 初始化 ArrayCollections 吗?

标签: php symfony doctrine-orm


【解决方案1】:

添加父关系时,没有ID没关系。

我无法详细解释为什么会发生这种情况,但我认为主要问题是,在多对多自引用中,带有 JoinTable 注释的属性可能是主实体。你可以说,它“持有”与该实体的所有其他关系。

您可以在更改函数$unit->addParent($parent) 时接收双向更新/插入。修改如下:

  public function addParent($parent)
  {
      $this->parents[] = $parent;
      $parent->addChild($this); // Add the relation in the proper way
  }

应该没问题!

问候!

【讨论】:

  • 有趣。虽然,在我看来,我认为拥有额外的注释并允许自动生成实体 getter 和 setter 会更干净。
  • 在玩弄之后,注释在执行schema:update 时导致table already exists 异常。所以这是正确的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 2019-06-23
相关资源
最近更新 更多