如何将具有*相同*对象引用的两个对象持久化到它们中



>想象一下这样的场景:我有一个实体,其中包含一些相关实体,我想按照一些逻辑进行更新。

public function updateRelated($foo) {
  foreach($foo->getBars() as $bar) {
    //modify bar attributes based on some logic
    $this->entity_manager->persist($bar); //entity manager was correctly instantiated
  }
}

$foo是以这种方式组成的对象

public function retrieveFoo() {
 $foo = new Foo();
 $bar = new Bar();
 $foobar = $this->entity_manager->getRepository('MyProject:FooBar');
 $bar->setFooBar($fooBar);
 $foo->setBar($bar);
 return $foo;
}

这个retrieveFoo()函数的调用次数比我调用updateRelated()的次数多(在检索到的foo对象上使用foreach,如下所示)。

public updateFooRelated($foo_object_array) {
 foreach($foo_object_array as $foo) {
  $this->updateRelated($foo);
 }
}

不幸的是,一些bar对象 - 调用它 - foo1具有与其他bar对象相同的fooBar对象 - 调用它 - foo2 这把事情搞砸了,因为当我返回updateRealted()foo2 对象,我已经坚持了$bar,这给了我以下错误

捕获的异常:类型的实体 我的应用程序\实体\栏 通过外国实体具有身份 但是,MyApplication\Entity\FooBar 此实体本身没有标识。你必须打电话 EntityManager#persist() 在相关实体上,并确保 标识符是在尝试持久化之前生成的 "我的应用程序\实体\栏"。 在插入后 ID 生成的情况下(例如 MySQL 自动增量或 PostgreSQL SERIAL)这意味着你必须调用EntityManager#flush() 在这两个持久操作之间。

当然,如果我对各种fooBar对象进行spl_object_has(),我会得到,可以预测的是,其中一些是同一个对象。

那么,奖励问题,实体管理器托管对象persist()会发生什么?


顺便说一句,我想再次获取fooBar对象将是一个解决方案,但是我如何告诉实体管理器(在这种情况下是存储库)给我另一个对象,以便基本上从数据库重新获取它或复制它开始管理?

为了避免出现这些问题,我会利用你在Foo和Bar之间的ManyToOne关系,我假设,并且只使用Foo对象来恢复和更新里面的柱线,如果你在你的实体关系中使用"级联持久",这是由教义自动完成的。

最新更新