如何使用Doctrine仅保留实体层次结构的第一级?

时间:2017-09-26 11:33:22

标签: php doctrine-orm orm doctrine persistence

我正在将ZF3应用程序的DBAL迁移到Doctrine并希望一步一步地继续。目前我正在使用Mapper个对象的层次结构。类似FooEntity层次结构中的每个实体都具有相应的FooMapper。嵌套实体的保存由嵌套的Mapper执行。每个Mappers都会使用Zend\Db\Sql\InsertZend\Db\Sql\Update保存其实体,并为Mapper的{​​{1}}等子实体调用正确的BarMapper。< / p>

现在,在我开始使用Doctrine的便捷功能(例如BarEntity)之前,我希望保留cascade={"persist"}的层次结构,并且仅使用{{1来执行嵌套实体的顶级保存}&amp; Mapper

但是当我尝试时

persist(...)

我收到错误

flush()

因此,Doctrine似乎尝试用其子实体保存整个实体,并且这种尝试在较低级别之一上失败。但为什么?我没有激活任何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; } 选项,并期望Doctrine只保存顶级。

为什么Doctrine会尝试保存整个实体,而不仅仅是顶级?如何让它只保存给定实体的顶级?

1 个答案:

答案 0 :(得分:1)

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

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

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

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

  1. 创建$this->entityManager->persist($externalServer);实体
  2. 后立即添加ExternalServer
  3. 使用AbstractEndpoint->externalServer注释cascade={"persist"}。您不想这样做,因为您只想将顶级实体保存到数据库,因此您需要手动保留它或不添加它是一种关系。
  4. 现在回答你的问题:

      

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

    以某种方式通过对象模型中的关系,Doctrine转到ExternalServer实体并发现它处于未加载状态。您不能仅保存顶级对象层次结构,并且链接到关系数据库中的未存在记录。如果您不希望Doctrine为您执行此操作 - 您必须自己处理这种情况或从关系中删除不持久的实体