2017-09-26 73 views
4

我正在將ZF3應用程序的DBAL遷移到Doctrine,並且希望一步一步地繼續。目前我正在使用Mapper對象的層次結構。像FooEntity層次結構中的每個實體都有一個根據FooMapper。嵌套實體的保存通過嵌套Mapper來執行。每個Mappers將其實體保存爲Zend\Db\Sql\InsertZend\Db\Sql\Update,併爲子實體調用適當的Mapper,如BarMapperBarEntity。現在如何僅使用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 'MyNamespace\DataObject\AbstractEndpoint#externalServer' that was not configured to cascade persist operations for entity: MyNamespace\DataObject\[email protected] 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 'MyNamespace\DataObject\ExternalServer#__toString()' to get a clue. 

所以,學說似乎試圖拯救其子實體整個實體,並在一個嘗試失敗較低的水平。但爲什麼?我沒有激活任何cascade選項,並期望Doctrine只保存最高級別。

爲什麼學說試圖保存整個實體而不僅僅是頂層?如何獲得它只保存給定實體的頂層?

+0

我不認爲有辦法。新的實體錯誤消息基本上是一個警告,您需要啓用級聯。鑑於您在兩個對象之間存在關係,Doctrine將嘗試堅持它。你當然可以刪除關係映射。 – Cerad

+0

@Cerad感謝您的評論。也許我理解'cascade = {「persist」}錯誤。我的期望是,對於'cascade = {「persist」}'註釋,相關的對象被保存,沒有 - 沒有。但是,如果級聯保存也沒有'cascade = {「persist」}',那麼這個註釋是什麼意思呢? – automatix

+0

這又是一個警告。一些人喜歡明確堅持所有的兒童實體,在這種情況下不需要級聯,警告消失。總的來說,關於ORM學說的一件事是,它只是以某種方式做事。你要麼住在一起,要麼不使用它。就個人而言,如果我已經有一個工作dbal的系統,那麼我會堅持下去。 – Cerad

回答

1

,因爲你在AbstractEndpoint->externalServer有一個新的實體(尚未持久化),並作爲cascade={"persist"}

換句話說,你剛剛創建了一個新的實體ExternalServer並沒有堅持就這個領域沒有被標註你得到這個錯誤並將其添加爲AbstractEndpoint->externalServer實體,該實體未被註釋爲cascade={"persist"}

因此,教義最終擁有這個新實體並且不知道如何處理它。爲了不丟失任何數據,引發這個異常。

爲了解決這個問題,你可以做兩件事情:

  1. 添加$this->entityManager->persist($externalServer);創建ExternalServer實體
  2. 標註AbstractEndpoint->externalServercascade={"persist"}之後。你不想這樣做,因爲你只想把頂級實體保存到數據庫中,所以你需要手動保存或不添加它是一種關係。

現在回答你的問題:

但是,爲什麼?我沒有激活任何級聯選項,並期望Doctrine只保存最高級別。

以某種方式通過對象模型中的關係原則下降到ExternalServer實體並發現它處於未執行狀態。您不能僅保存鏈接到關係數據庫中的未記錄記錄的頂層對象層次結構。如果你不想讓學說爲你做 - 你必須自己處理這種情況,或從關係中刪除不存在的實體

相關問題