2012-11-05 231 views
4

我使用PHP腳本Doctrine 2,做題主要是:外鍵約束失敗(MySQL的)

$entityManager->transactional(function($em) { 
    $foreignObject = new DoctrineEntities\ForeignTable(); 
    $em->persist($foreignObject); 
    $em->flush(); 
    $aObject = new DoctrineEntities\A(); 
    $aObject->ForeignID = $foreignObject->ID; 
    $em->persist($aObject); 
    $em->flush(); 
}); 

我得到的完整性約束違規:

一個外鍵約束失敗(dbName.A,約束A_ForeignID外鍵(ForeignID)參考文獻ForeignTableID)ON DELETE NO ACTION ON UPDATE NO ACTION)

我的猜測是在提交之前檢查約束,並且它不檢查是否創建了尚未提交的插入可能會使約束通過而不是失敗。但我真的希望這兩個插入語句包裝在同一個事務中。那麼我能做什麼?

UPDATE

我感動$em->persist($aObject); $em->flush();從交易中,我仍然得到同樣的錯誤。顯然,我的猜測是錯誤的......但後來我真的不知道是什麼原因導致了錯誤。


SQL語境

CREATE TABLE `A` (
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    `ForeignID` int(11) NOT NULL, 
    PRIMARY KEY (`ID`), 
    KEY `A_ForeignID` (`ForeignID`), 
    CONSTRAINT `A_ForeignID` FOREIGN KEY (`ForeignID`) REFERENCES `ForeignTable` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci 

ForeignTable

CREATE TABLE `ForeignTable` (
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`ID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci 
+0

你可以嘗試在SQLfiddle做一個示例?如果我不錯讀它聽起來像它應該「只是工作」。 –

+0

@Joachim Isaksson |我一直試圖嚴格在mysql中重現這個問題,但我一直無法。也許這個問題與Doctrine處理交易的方式有關。 – Shawn

+0

很難說沒有看到代碼,但是如果你使用的是教條,你可能會嘗試在持久符之間刷新,所以它們不會被重新排序。 –

回答

1

我建議閱讀關於MySQL數據完整性和FKs,然後Doctrine associations,數據完整性由MySQL檢查InnodDB表。你在做什麼是不對的,它應該是

$entityManager->transactional(function($em) { 
    $foreignObject = new DoctrineEntities\ForeignTable(); 
    $em->persist($foreignObject); 

    $aObject = new DoctrineEntities\A(); 
    $aObject->setForeign($foreignObject); 
    $em->persist($aObject); 

    $em->flush(); 
}); 
+0

我正在使用現有的數據庫模式。 「Doctrine associations」鏈接僅提供瞭如何使用Doctrine通過創建新數據庫模式來建立關聯的文檔。你有什麼關於模式已經存在的情況的文獻嗎? – Shawn

0

我解決了這個問題。這是其他地方完全無關我的問題..我要接受getme的答案,因爲接受這個答案真的不會幫助其他任何人在這裏...