如何用教义只执行实体层次结构的第一级?



我正在将 ZF3 应用程序的 DBAL 迁移到 Doctrine,并希望一步一步地继续前进。目前,我使用的是Mapper对象的层次结构。类似FooEntity层次结构中的每个实体都有一个 根据FooMapper。嵌套实体的保存由嵌套Mapper执行。每个Mappers都使用ZendDbSqlInsertZendDbSqlUpdate保存其实体,并为子实体调用正确的Mapper,例如BarMapper用于BarEntity

现在,在我开始使用 Doctrine 的便利功能(如cascade={"persist"})之前,我想保留Mapper的层次结构,并且只是使用persist(...)&flush()执行嵌套实体顶层的保存。

但是当我尝试时

public function save(AbstractDataObject $dataObject)
{
$newLogicalConnection = $this->logicalConnectionMapper->save($dataObject->getLogicalConnection());
$newUser = $this->userMapper->save($dataObject->getUser());
$dataObject->setLogicalConnection($this->entityManager->find(LogicalConnection::class, $newLogicalConnection->getId()));
$dataObject->setUser($this->entityManager->find(User::class, $newUser->getId()));
$this->entityManager->persist($dataObject);
$this->entityManager->flush();
return $dataObject;
}

我收到错误

A new entity was found through the relationship 'MyNamespaceDataObjectAbstractEndpoint#externalServer' that was not configured to cascade persist operations for entity: MyNamespaceDataObjectExternalServer@000000006098ccff0000000068c23676. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'MyNamespaceDataObjectExternalServer#__toString()' to get a clue.

因此,Doctrine似乎试图用它的子实体来拯救整个实体,而这种尝试在一个较低的层面上失败了。但是为什么?我没有激活任何cascade选项,并期望 Doctrine 只保存顶级。

为什么教义试图拯救整个实体,而不仅仅是顶层?以及如何让它只保存给定实体的顶层?

您收到此错误是因为您在AbstractEndpoint->externalServer中有一个新实体(尚未保留),并且此字段未注释为cascade={"persist"}

换句话说,您刚刚创建了一个新实体ExternalServer并且没有保留它并将其添加为与未注释为AbstractEndpoint->externalServer实体的关系cascade={"persist"}

因此,教义最终拥有了这个新实体,并且不知道如何处理它。为了不丢失任何数据,将引发此异常。

要解决此问题,您可以做两件事:

  1. 创建实体后立即添加$this->entityManager->persist($externalServer);ExternalServer
  2. cascade={"persist"}注释AbstractEndpoint->externalServer。您不想这样做,因为您只想将顶级实体保存到数据库中,因此您需要手动保留它或不添加它是一个关系。

现在回答你的问题:

但是为什么?我没有激活任何级联选项,并希望 Doctrine 只保存顶级。

不知何故,通过对象模型中的关系,Doctrine 向下到ExternalServer实体并发现它处于未持久状态。您不能只保存对象层次结构的顶层,并链接到关系数据库中不存在的记录。如果你不希望教义为你做这件事 - 你必须自己处理这种情况,或者从关系中删除未持久化的实体

相关内容

  • 没有找到相关文章

最新更新