>想象一下这样的场景:我有一个实体,其中包含一些相关实体,我想按照一些逻辑进行更新。
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对象来恢复和更新里面的柱线,如果你在你的实体关系中使用"级联持久",这是由教义自动完成的。