1

想象一下这种情况:我有一个实体,其中包含一些我想要更新的相关实体,遵循一些逻辑。

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对象将是一个解决方案,但是我如何告诉实体管理器(在这种情况下是存储库)给我另一个对象,所以基本上,从数据库重新获取它或复制它并开始管理?

4

1 回答 1

0

为了避免出现这些问题,我假设我会利用 Foo 和 Bars 之间的 ManyToOne 关系,并且只使用 Foo 对象来检索和更新内部的 bar,如果你使用“级联”,这将由学说自动完成坚持”在您的实体的关系中。

于 2013-10-24T09:36:52.820 回答