Php 条令仅在foreach循环后插入一条记录

Php 条令仅在foreach循环后插入一条记录,php,doctrine,symfony4,entitymanager,Php,Doctrine,Symfony4,Entitymanager,我有一个简单的数组,其中包含一些需要插入数据库的值。在所有值中,只有最后一个实际插入 当我把flush()在循环中,确实会插入记录 当我在刷新之前转储实体管理器时(在foreach之外),我确实看到了对所有值(实体)的引用 但是,只插入最后一条记录。它的id是3,所以其他的好像都丢在什么地方了 $values=[ “val1”、“val2”、“val3” ]; foreach($value作为$value){ $i=新MyEntityClass(); $i->setVerified(假); $i

我有一个简单的数组,其中包含一些需要插入数据库的值。在所有值中,只有最后一个实际插入

当我把
flush()在循环中,确实会插入记录

当我在刷新之前转储实体管理器时(在foreach之外),我确实看到了对所有值(实体)的引用

但是,只插入最后一条记录。它的id是3,所以其他的好像都丢在什么地方了

$values=[
“val1”、“val2”、“val3”
];
foreach($value作为$value){
$i=新MyEntityClass();
$i->setVerified(假);
$i->setName($value);
$this->em->persist($i);
}
$this->em->flush();
更新: 我连接了一个eventlistener来进行前刷新和后刷新

公共函数preFlush(PreFlushEventArgs$args){
$em=$args->getEntityManager();
foreach($em->getUnitOfWork()->GetScheduleIdentityInsertions()作为$entity){
转储($entity->getName());
}
}
公共函数postFlush(PostFlushEventArgs$args){
dd($args->getEntityManager()->getUnitOfWork()->getScheduledEntityInsertions());
}
在预冲洗中,所有值都被清晰打印,并且后冲洗转储为空

更新2: 我使用的是uuid二进制时间,如下所示

  /**
   * @ORM\Id
   * @ORM\Column(type="uuid_binary_ordered_time", unique=true)
   * @GeneratedValue(strategy="CUSTOM")
   * @CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidOrderedTimeGenerator")
   * @Groups({"uuid"})
   */
  protected $id;
使用
10.4.8-MariaDB
phpv7.3.10

更新3: 我仍在努力解决这个问题,现在有了一个不同的场景,但仍然遇到了多个操作未执行的问题。这可能与数据库配置有关,而不是与条令有关吗

案例:从表A和表B收集数据,将数据插入表C,从表A删除记录

根据@Jakumi的建议(或查看日志),我可以看到正在执行以下查询(表A中的行已删除,但表C中没有新行):


您为什么不在事件发生后立即使用刷新,如下所示:

$values = [
    "val1", "val2", "val3"
];

foreach ($values as $value) {
  $i = new MyEntityClass();
  $i->setVerified(false);
  $i->setName($value);
  $this->em->persist($i);
  $this->em->flush();
}
或者更好:

public function save(MyEntityClass $myEntityClass): void
{
    $this->em->persist($myEntityClass);
    $this->em->flush();
}
在实体的存储库中,并在希望单独保存相关实体时使用它

编辑-另一种尝试方法

$values = [
    "val1", "val2", "val3"
];

$this->em->getConnection()->beginTransaction();

foreach ($values as $value) {
  $i = new MyEntityClass();
  $i->setVerified(false);
  $i->setName($value);
  $this->em->persist($i);
}

try {
    $this->em->flush();
    $this->em->getConnection()->commit();
} catch (Exception $e) {
    $this->em->getConnection()->rollback();
    $this->em->close();
    throw $e;
}
还可以在$id的定义中添加行:

/**
* @var \Ramsey\Uuid\UuidInterface
*
* @ORM\Id
* @ORM\Column(type="uuid_binary_ordered_time", unique=true)
* @GeneratedValue(strategy="CUSTOM")
* @CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidOrderedTimeGenerator")
* @Groups({"uuid"})
*/
protected $id;
编辑-使用type=“uuid”

更新$id的声明

/**
 * Entity constructor.
 *
 * @param UuidInterface|null $uuid
 *
 * @throws \Exception
 */
public function __construct(UuidInterface $uuid = null)
{
    if (null === $uuid) {
        $uuid = Uuid::uuid4();
    }
    $this->id = $uuid;

    [Other fields ...]
}

 /**
 * @var \Ramsey\Uuid\UuidInterface
 *
 * @ORM\Id
 * @ORM\Column(type="uuid")
 */
protected $id;

/**
 * @return UuidInterface|null
 */
public function getId(): ?UuidInterface
{
    return $this->id;
}

这样做,你应该排除它是$id弄乱了条令。。。我们可以在其他地方进行调查

我仍然不确定是什么导致了这一问题,但我确实设法“解决”了这个问题。为此,我从我的开发环境中完全删除了MariaDB及其组件和数据库本身

在重新安装MariaDB、运行mysql\u secure\u安装、重新创建数据库和运行迁移之后,所有这些都按预期工作


$this->em->flush()在foreach外部插入所有记录,我的第二个问题案例也是如此。

您的实体的id生成器是什么?也许最后一个会覆盖前一个?@Jakumi谢谢你的回答,我更新了问题。我用的是uuid\u二进制\u有序时间。这可能是一个非常奇怪的想法,但是。。。您是如何将第一个实体放入数据库的?如果是在相同的symfony安装中完成的,您是否尝试过以相同的方式添加第二个实体?因为它不应该工作,因为“克隆”本质上只是一个新实体,所以它也不应该工作。此外,您的实体是否与其他实体有任何关系?如果是,请张贴他们的定义(两面)。还要仔细查看探查器,看看运行了哪些数据库查询。@Jakumi这纯粹是一个将记录插入数据库的命令脚本。出于测试目的,我多次删除了整个数据库,编写了新的迁移脚本,等等。表或实体上没有设置任何关系。实体类是通过Symfony maker捆绑包(make:Entity)生成的。我真的不明白你说的“不应该工作”是什么意思。。在每个循环中,都会创建一个新实体,并将其保存在实体管理器中。这些应该有不同的参考,所以它应该有效?!哦,我。。。把这个问题和另一个问题混淆了。很抱歉o(您的情况实际上非常奇怪,很难找到入口点。您能否通过以下方式找出实际执行的查询:因为在N条记录的情况下,将导致N个insert查询。在N个PERSISTER之后刷新时,所有持久化实体的insert查询应为1个。@Svdb这在很大程度上取决于实体的设置和使用方式。)它可能有各种各样的关系,当然在我更新了上面代码的事务中有一些不规则的东西,请尝试一下谢谢你的回复。我尝试了你的第二种方法,使用了``beginTransaction()commit()和rollback()“``结果很不幸保持不变。您所说的“在$id的定义中添加行”是什么意思?要添加@var定义?好的,您可以做另一个测试。(否则,我们会等待别人帮我们一把:-)。使用类型“uuid”而不是“uuid\u binary\u ordered\u time”,更新上面帖子中的代码我必须承认,你在寻找不同的方法来实现这一点上是非常有创造性的:)但不幸的是,我必须报告,这并没有改变结果。
/**
 * Entity constructor.
 *
 * @param UuidInterface|null $uuid
 *
 * @throws \Exception
 */
public function __construct(UuidInterface $uuid = null)
{
    if (null === $uuid) {
        $uuid = Uuid::uuid4();
    }
    $this->id = $uuid;

    [Other fields ...]
}

 /**
 * @var \Ramsey\Uuid\UuidInterface
 *
 * @ORM\Id
 * @ORM\Column(type="uuid")
 */
protected $id;

/**
 * @return UuidInterface|null
 */
public function getId(): ?UuidInterface
{
    return $this->id;
}