Doctrine2 - 通过这种关系找到了一个新的实体[...]

问题描述 投票:2回答:5

哇,这很奇怪:

$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();

但没有改变。

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


UPDATE

我已经迁移了db钩子之外的所有代码,并且我已经创建了一个新服务,它将执行几乎相同的钩子,但是必须在flush()之后显式调用,但是,没有任何改变。我还尝试将spl_obj_hash用于实体管理器,以检索有关将对象刷新到db的实体管理器的信息,以及将从db检索$foo并尝试持久化$bar的“另一个”。这是结果:

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

如果我没错,它们就是同一个实体管理器对象。我其实很困惑......


更新 - 工作代码

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

如果我使用第一段代码(从$foo本身检索$entity)并且仅冲洗$bar,则仍然存在错误。

如果我使用第二段代码(从实体管理器中检索$foo)并仅保留$bar,则所有工作都正常(如果我在没有参数的情况下调用$flush(),那么问题仍然存在)

symfony orm doctrine-orm
5个回答
4
投票

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

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

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


1
投票

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

$这 - > getDoctrine() - > getManager() - >明确();


0
投票

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

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

$em->merge($foo);

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

另外,请记住在数据库操作之后执行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

试试这个,让我知道结果


0
投票

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

$bar = new Bar();

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

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

[1] Doctrine - A new entity was found through the relationship


-4
投票

从你的代码中不太清楚,但我认为你创建了一个新的$ foo,但是你不保存它以保存$ bar。试试这个:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.