想象一下这种情况:我有一个实体,其中包含一些我想要更新的相关实体,遵循一些逻辑。
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()
(在检索到的对象上使用 foreach foo
,如下所示)。
public updateFooRelated($foo_object_array) {
foreach($foo_object_array as $foo) {
$this->updateRelated($foo);
}
}
不幸bar
的是,一些对象 - 调用它 -foo1
具有与fooBar
其他bar
对象相同的对象 - 调用它 -foo2
这把事情搞砸了,因为当我返回对象时,我已经坚持updateRealted()
了,这给了我以下错误foo2
$bar
捕获的异常:MyApplication\Entity\Bar 类型的实体通过外部实体 MyApplication\Entity\FooBar 具有标识,但是该实体本身没有标识。您必须在相关实体上调用 EntityManager#persist() 并确保在尝试保留“MyApplication\Entity\Bar”之前生成了一个标识符。在 Post Insert ID Generation(例如 MySQL Auto-Increment 或 PostgreSQL SERIAL)的情况下,这意味着您必须在两个持久化操作之间调用 EntityManager#flush()。
当然,如果我spl_object_has()
对各种fooBar
对象进行分析,我会发现,可以预见的是,其中一些是同一个对象。
那么,额外的问题是,persist()
实体管理器托管对象之后会发生什么?
顺便说一句,我想再次获取fooBar
对象将是一个解决方案,但是我如何告诉实体管理器(在这种情况下是存储库)给我另一个对象,所以基本上,从数据库重新获取它或复制它并开始管理?