Php 为什么即使我事先检查了多对多关系是否存在,学说仍试图复制多对多关系?为什么它会在同花顺时随机崩溃?

Php 为什么即使我事先检查了多对多关系是否存在,学说仍试图复制多对多关系?为什么它会在同花顺时随机崩溃?,php,symfony,doctrine-orm,many-to-many,undefined-index,Php,Symfony,Doctrine Orm,Many To Many,Undefined Index,我真的很难受,条令没能按预期发挥作用 我的代码尝试执行的操作。 我正在我的symfony3web应用程序中编写一个CLI命令,用来整理数据库中的标记表。有演员,有标签。参与者和标记之间存在多对多关系(双向)。我的命令导入一个CSV文件,其中一列列出了当前标记,而另一列中有一些替换标记。它逐行遍历文件,查找现有标记,读取其与参与者的所有当前关系,删除标记,创建新标记(替换)或使用现有标记,并将已删除标记的所有参与者关系附加到该文件 代码(其关键部分) 我通过从Actor->Tag-relatio

我真的很难受,条令没能按预期发挥作用

我的代码尝试执行的操作。

我正在我的symfony3web应用程序中编写一个CLI命令,用来整理数据库中的标记表。有演员,有标签。参与者和标记之间存在多对多关系(双向)。我的命令导入一个CSV文件,其中一列列出了当前标记,而另一列中有一些替换标记。它逐行遍历文件,查找现有标记,读取其与参与者的所有当前关系,删除标记,创建新标记(替换)或使用现有标记,并将已删除标记的所有参与者关系附加到该文件

代码(其关键部分)

我通过从Actor->Tag-relationdefinition中删除
indexBy:id
(它是偶然出现的)来修复上述问题

另外,当我做一些理论上无害的修改时,比如取消注释注释注释注释的
flush()
调用或者不使用大事务,我得到了这样的结果

即使没有对代码进行任何修改,在导入的某个时刻,我仍然会得到以下结果:

  [Symfony\Component\Debug\Exception\ContextErrorException]
  Notice: Undefined index: 000000001091cbbe000000000b4818c6


Exception trace:
 () at /src/__sources/atm/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2907
 Doctrine\ORM\UnitOfWork->getEntityIdentifier() at /src/__sources/atm/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php:543
 Doctrine\ORM\Persisters\Collection\ManyToManyPersister->collectJoinTableColumnParameters() at /src/__sources/atm/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php:473
 Doctrine\ORM\Persisters\Collection\ManyToManyPersister->getDeleteRowSQLParameters() at /src/__sources/atm/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php:77
 Doctrine\ORM\Persisters\Collection\ManyToManyPersister->update() at /src/__sources/atm/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:388
 Doctrine\ORM\UnitOfWork->commit() at /src/__sources/atm/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:359
 Doctrine\ORM\EntityManager->flush() at /src/__sources/atm/src/AppBundle/Command/AtmReplaceTagsCommand.php:176
 AppBundle\Command\AtmReplaceTagsCommand->doReplace() at /src/__sources/atm/src/AppBundle/Command/AtmReplaceTagsCommand.php:60
 AppBundle\Command\AtmReplaceTagsCommand->execute() at /src/__sources/atm/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:262
 Symfony\Component\Console\Command\Command->run() at /src/__sources/atm/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:848
 Symfony\Component\Console\Application->doRunCommand() at /src/__sources/atm/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:190
 Symfony\Component\Console\Application->doRun() at /src/__sources/atm/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:80
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /src/__sources/atm/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:121
 Symfony\Component\Console\Application->run() at /src/__sources/atm/bin/console:28
每隔几行做一次
$em->clear()
没有帮助

我尝试的

  • 我尝试更改
    flush()
    调用序列,这通常会导致奇怪的未定义索引错误
  • 我试着对那笔大交易发表评论(没有用)
  • 我试着在每20条记录之后调用
    $em->clear()
    ,这也没有改变任何东西
我真的非常感谢你在这方面的帮助

其他信息

参与者->标记关系的YAML定义(对于参与者实体):

标签->参与者关系的YAML定义(针对标签实体):

Tag::addActor()
函数定义

public function addActor(\AppBundle\Entity\Actor $actor)
{
    $this->actor[] = $actor;
    $actor->addTag($this);

    return $this;
}
public function addTag(\AppBundle\Entity\Tag $tag)
{
    $this->tags[] = $tag;

    $this->serializeTagIds();

    return $this;
}
Actor::addTag()
函数定义

public function addActor(\AppBundle\Entity\Actor $actor)
{
    $this->actor[] = $actor;
    $actor->addTag($this);

    return $this;
}
public function addTag(\AppBundle\Entity\Tag $tag)
{
    $this->tags[] = $tag;

    $this->serializeTagIds();

    return $this;
}

如果您需要任何其他信息,请询问。非常感谢。

问题出在您的
标记::addActor()
标记::addTag()
函数中。--在添加新条目之前,它们在不检查集合中的内容的情况下进行递归调用,这就是为什么会得到重复的插入

更改函数,以便首先检查
ArrayCollection
实例,如下所示:

public function addActor(\AppBundle\Entity\Actor $actor)
{
    if (!$this->actor->contains($actor)) {
        $this->actor->add($actor);
    }

    $actor->addTag($this);

    return $this;
}

public function addTag(\AppBundle\Entity\Tag $tag)
{
    if (!$this->tags->contains($tag)) {
        $this->tags->add($tag);
    }

    $this->serializeTagIds();

    return $this;
}
除此之外,我假设两个实体的构造函数都将属性初始化为一个新的
ArrayCollection
实例,否则将出现“tryingtocalladd()onnull”错误。我还假设您有
使用条令\Common\Collections\ArrayCollection位于这些类的顶部

对于标记类:

public function __construct()
{
    $this->actor = new ArrayCollection();
}
对于Actor类:

public function __construct()
{
    $this->tags = new ArrayCollection();
}
加载现有实体时,这些将不会覆盖/擦除关系。它只是确保在尝试向新实体添加元素之前,已正确设置了一个
ArrayCollection
实例

关键点:YAML定义使用属性名“actors”,但类函数引用的是
$this->actor
。不应该是
$this->actors
如果这是真的,请调整上述示例以使用
$this->actors
,而不是
$this->actor


最后,在这种情况下,不要使用
$em->clear()
。这将导致实体管理器知道的所有对象都将处于非托管状态,这意味着在您再次
$em->merge()
它们之前,它们不会在您的函数中保留任何进一步的更改。

因此我部分地解决了这个问题。从Actor->Tag-relations定义中删除
indexBy:id
行后,我不再获得多对多重复关系。但是,无论我做什么,我仍然会得到
未定义索引
错误:-(类似的问题在这里,注释$em->clear()可以解决问题。仍然在寻找更好的解决方案。感谢回复人!很长时间没有机会使用条令,但我肯定会在某个时候测试您的解决方案。
public function __construct()
{
    $this->actor = new ArrayCollection();
}
public function __construct()
{
    $this->tags = new ArrayCollection();
}