2

哇,这很奇怪:

$bar = new Bar();

$foo = $entity->getFoo(); 
$bar->setFoo($foo);

$em->persist($bar); 
$em->flush();

我收到以下消息

通过关系发现了一个新实体 [....]

通过在网上阅读,我了解到如果从两个不同的实体管理器获取两个对象,一个管理器将不知道从另一个管理器获取的实体。因为在这里我进入了一个“db hook”(postPersist)并且我已经从 DIC 注入了管理器,所以我尝试更改我的代码以达成一致:

$bar = new Bar();

$foo_id = $entity->getFoo()->getId();
$foo = $em->getRepository('MyBundleName:Foo')->findOneBy(array('id'=>$foo_id));
$bar->setFoo($foo);

$em->persist($bar); 
$em->flush();

但没有任何改变。

有人可以指出我正确的方向,最重要的是,解释这里发生了什么?


更新

我已经迁移了 db hooks 之外的所有代码,并且我创建了一个新服务,它将执行与 hooks 几乎相同的事情,但必须在之后显式调用flush()非常奇怪,但是没有任何改变。我还尝试使用spl_obj_hash实体管理器来检索有关将对象刷新到数据库中的实体管理器和$foo将从数据库中检索并尝试持久化的“其他”的信息$bar。这是结果:

SPL_OBJ ENTITY MANAGER - 1: 0000000021770e03000000001eda54f7
SPL_OBJ ENTITY MANAGER - 2: 0000000021770e03000000001eda54f7

如果我没记错的话,它们是同一个实体管理器对象。其实我很迷茫...


更新 - 工作代码

我找到了一个可以完成工作的“代码组合”,但我仍然对此感到很困惑。

如果我使用第一段代码(其中$foo$entity自身检索)并且仅刷新$bar,错误仍然存​​在。

如果我使用第二段代码($foo从实体管理器中检索到)并且仅持久化$bar,则一切正常(显然,如果我$flush()在没有参数的情况下调用,问题仍然存在)

4

5 回答 5

6

我遇到了同样的问题并解决了它,我发布它是因为我没有在任何地方看到它,它可能对某人有所帮助。

我有一个解析数据并将其保存到实体的服务,我正在向其提供 entityManager 和子实体的服务。我开始在坚持上遇到同样的错误。使用merge()并没有帮助,因为它只是给我带来了"A managed dirty+entity [...]"错误。

经过一番挖掘,似乎就 Doctrine 而言,我为我的服务提供的实体来自不同的 entityManager,所以如果你使用它来持久化,你实际上必须从服务内部的 entityManager 获取实体。

于 2014-07-31T12:34:23.143 回答
1

我通过清除清除来修复我的

$this->getDoctrine()->getManager()->clear();

于 2014-04-03T17:17:24.957 回答
0

试试: $em->merge($bar);

$bar = new Bar();

$foo = $entity->getFoo(); 
$bar->setFoo($foo);

$em->merge($bar); 
$em->flush();

[1] Doctrine - 通过关系发现了一个新实体

于 2014-01-02T15:34:07.203 回答
0

我不确定,因为我以前从未遇到过这个问题,现在我无法复制它。但我会给你一些我会尝试的选择:

如果两个实体管理器使用相同的数据库,您可以将(http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html#merging-entities)实体合并到另一个实体经理。在这种情况下,它看起来像这样:

$em->merge($foo);

这可确保实体$foo由您的 entitymanager 管理。

另外,请记住 postPersist在数据库操作之后执行。我认为,如果您以 prepersist 方法尝试修改后的代码,您会有更好的机会。

正如文档所说:

prePersist  - The prePersist event occurs for a given entity before the respective
              EntityManager persist operation for that entity is executed.

postPersist - The postPersist event occurs for an entity after the entity has 
              been made persistent. It will be invoked after the database insert
              operations. Generated primary key values are available in the 
              postPersist event.

完整的文档可以在这里找到:http: //docs.doctrine-project.org/en/2.0.x/reference/events.html#lifecycle-events

试试这个,让我知道结果

于 2013-10-09T14:55:40.620 回答
-4

从你的代码看不是很清楚,但是我认为你创建了一个新的$foo,但是你之前没有保存它来保存$bar。尝试这个:

$em->persist($foo); 
$em->flush();    
$bar->setFoo($foo);
$em->persist($bar); 
$em->flush();

通常,您可以通过在实体关联上使用 cascade=persist 来避免这种情况。

于 2013-10-09T13:55:13.680 回答