2011-05-06 181 views
2

當我使用實體管理器刪除實體時,出現了一個奇怪的錯誤。拋出一個例外說「一個新的實體是通過未配置爲級聯持久性操作的關係找到的」但我沒有新的實體。我認爲這可能是教義上的一個錯誤,但我認爲我會先問一些問題,以確保在填寫報告之前我沒有做錯任何事情。Doctrine 2刪除實體問題

相關的代碼:

<?php 
$em = Doctrine\ORM\EntityManager::create(array('driver' => 'pdo_sqlite', 'memory' => true), $config); 

$qb = $em 
    ->getRepository('Bar') 
    ->createQueryBuilder('bar1') 
    ->select('bar1, foo1, bar2') 
    ->join('bar1.foo', 'foo1') 
    ->join('foo1.bar', 'bar2') 
; 

$qb->getQuery()->getResult(); 

$bar = $em->getRepository('Bar')->findOneBy(array('id' => 20)); 

$em->transactional(function($em) use ($bar) { 
    $em->remove($bar); 
    $em->flush(); 
}); 

如果我刪除一個包裝刪除和清空操作刪除作品$em->transactional。另外,如果我刪除$qb->getQuery()->getResult();作爲以前的查詢,則remove和flush調用起作用。

我得到的錯誤是:

 
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'A new entity was found through a relationship that was not configured to cascade persist operations: [email protected] Explicitly persist the new entity or configure cascading persist operations on the relationship.' in doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php:576 
Stack trace: 
    #0 doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php(495): Doctrine\ORM\UnitOfWork >computeAssociationChanges(Array, Object(Doctrine\ORM\PersistentCollection)) 
    #1 doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php(537): Doctrine\ORM\UnitOfWork->computeChangeSet(Object(Doctrine\ORM\Mapping\ClassMetadata), Object(Foo)) 
    #2 doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php(256): Doctrine\ORM\UnitOfWork->computeChangeSets() 
    #3 doctrine2-orm/lib/Doctrine/ORM/EntityManager.php(334): Doctrine\ORM\UnitO in doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php on line 576 

一個完整的工作示例可以在這個gist找到。

+0

你嘗試使用try catch而不是transactional/closure嗎?這可能是綁定$ bar的問題。您也可以嘗試在use語句中添加一個&符號:'use(&$ bar)'作爲一個附註,我沒有看到事務性的點;它只是讓你做交易而不讓你處理錯誤。 – rojoca 2011-05-06 14:35:19

+0

嘗試了所有這些操作,包括將電話轉移到事務性呼叫中的「$ bar」。您仍然可以通過將事務包裝在try-catch塊中來處理事務性錯誤。 – MitMaro 2011-05-06 14:40:52

回答

4

我填補了bug report後最終得出這個結論。

transactional在內部執行了刷新,並且雙重刷新導致了此問題。我不認爲雙重沖洗應該破壞事情,但我沒有爭辯這一點。

這樣說我沒有正確使用transactional,Doctrine 2具有隱式事務,並且不需要在transactional中包裝數據庫調用,除非在非常特定的情況下。

從學說2文件,當你想在工作單位或自定義DBAL操作

顯式的事務劃分在需要的時候你想使用的需要的了EntityManager API的一些方法活躍的交易。這樣的方法會拋出一個TransactionRequiredException來通知你這個需求。

2

transactional()用於刷新操作。沖洗已經取得了多次重複