2017-10-17 152 views
0

我有一個由Zend\Form數據自動補水而創建的複雜/嵌套對象。現在我想用Doctrine 2保存它。最好的情況是在頂層調用一個persist(...)和一個flush(...)。但它不這樣工作。所以現在我有以下問題:如何僅在實體不存在的情況下僅保留一個關係的一端,而另一端僅保留一個關係?

有對象UserOrder。關係是1:n(所以,1UsernOrder s)。 User已經存在。當UserJoe試圖保存的多於一個Order(例如它的第二順序),將發生錯誤:

一個新的實體是通過中沒有配置於以下關係'... \訂單#用戶發現對實體級聯持久化操作:... \ User @ 000000003ba4559d000000005be8d831。解決此問題:顯式調用此未知實體上的EntityManager#persist()或配置級聯將該關聯保存在映射中,例如@ManyToOne(..,cascade = {「persist」})。如果你找不到哪個實體導致問題實現'... \ User #__ toString()'以獲得線索。

還好吧,我加cascade={"persist"}(儘管它沒有意義在這裏,但無論如何,只是嘗試一下):

class Order 
{ 
    ... 
    /** 
    * @var User 
    * 
    * @ORM\ManyToOne(targetEntity="User", cascade={"persist"}) 
    */ 
    protected $user; 
    ... 
} 

現在它的工作原理,如果給定User不存在:創建了OrderUser

但如果User存在,出現錯誤:在執行 '(?,?,?,)INSERT INTO用戶(用戶名,角色,創建,更新)VALUES' 有發生

例外PARAMS [ 「名爲myUsername」, 「成員」,NULL,NULL]:

SQLSTATE [23000]:完整性約束衝突:關鍵1062重複條目「名爲myUsername 'username_UNIQUE'

如何處理薩維那麼,那麼User只會被保存,如果它不存在?

+0

你驗證用symfony形式(或僅驗證組件)這個對象?看一看[UniqueEntity Constraints](https:// symfony。com/doc/current/reference/constraints/UniqueEntity.html) – Matteo

+0

感謝您的評論,但我使用的是Zend \ Form,而不是Symfony。爲了驗證表單,我使用了Zend驗證功能。 – automatix

+0

幾乎每次遇到Doctrine錯誤「通過關係'... Order#user'發現了一個新實體,該實體沒有被配置爲級聯實體的持久化操作」我發現我做了一些錯誤的事情,通常是小。 用英語說,錯誤告訴你訂單已被保留,但與其關聯的用戶沒有被保存。這意味着被分配的用戶不會被Doctrine知道爲數據庫中的實體。仔細檢查你的代碼,確認你實際上是分配一個合適的用戶並且它是一個有效的用戶。 – MEmerson

回答

0

解決的辦法是在保存引用實體之前堅持User。如果它不存在,它需要創建(persist ED和ED flush)第一:

$user = $this->entityManager->getRepository(User::class)->findOneBy(
    ['username' => $dataObject->getUser()->getUsername()] 
); 
if (! $user) { 
    $this->entityManager->persist($dataObject->getUser()); 
    $this->entityManager->flush($dataObject->getUser()); 
    $user = $this->entityManager->getRepository(User::class)->findOneBy(
     ['username' => $dataObject->getUser()->getUsername()] 
    ); 
} 
$dataObject->setUser($user); 

$this->entityManager->persist($dataObject); 
$this->entityManager->flush(); 

而且cascade={"persist"}不應該使用,因爲它實際上並沒有在這種情況下才有意義。


編輯

或者更簡單:

$user = $this->entityManager->getRepository(User::class)->findOneBy(
    ['username' => $dataObject->getUser()->getUsername()] 
); 
if ($user) { 
    $dataObject->setUser($user); 
} else { 
    $this->entityManager->persist($dataObject->getUser()); 
} 

$this->entityManager->persist($dataObject); 
$this->entityManager->flush(); 
相關問題