2014-09-30 18 views
5

我在問及回答這個問題以備將來參考,因爲我認爲我已經找到了一個體面的解決方案來解決DbUnit的常見問題。我希望它能幫助某個人,在某個地方。DbUnit無法清除插入:外鍵約束

我正在使用DbUnit 2.5.0TestNG 6.8.8。我的用例是由3個實體組成的數據庫的一部分。有一個ServiceUser它持有AdministrableUserGroup的外鍵。

我跟着大多數代碼示例的從http://city81.blogspot.com/2011/03/testing-jpa-entities-using-dbunit.html

public abstract class AbstractDatabaseTest { 
    protected EntityManager em; // initialized elsewhere 
    private IDatabaseConnection connection; 
    private IDataSet dataset; 

    @BeforeClass 
    private void setupDatabaseResource() throws Exception { 
     // using Hibernate 
     connection = new DatabaseConnection(((SessionImpl) (em.getDelegate())).connection()); 
     connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory()); 

     // full database export 
     IDataSet fullDataSet = connection.createDataSet(); 

     final String datasetPath = String.format("%s%s", RESOURCE_FOLDER, "Testing.xml"); 
     FlatXmlDataSet.write(fullDataSet, new FileOutputStream(datasetPath)); 

     FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder(); 
     flatXmlDataSetBuilder.setColumnSensing(true); 
     dataset = flatXmlDataSetBuilder.build(new FileInputStream(datasetPath)); 
    } 

    @AfterMethod 
    public void cleanDB() throws Exception { 
     em.getTransaction().begin(); 
     DatabaseOperation.CLEAN_INSERT.execute(connection, dataset); 
     em.getTransaction().commit(); 
    } 
} 

這樣做的結果是以下XMLDataSet(省略數據):

<dataset> 
    <administrable/> 
    <serviceuser/> 
    <usergroup/> 
</dataset> 

TestNG執行@AfterMethod,得到以下例外:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException 
Cannot delete or update a parent row: a foreign key constraint fails (`testing_db`.`serviceuser`, CONSTRAINT `FK_gyylcfbhpl2ukqs5rm7sq0uy8` FOREIGN KEY (`userGroup_id`) REFERENCES `usergroup` (`id`)) 

回答

11

問題是我上面創建的XMLDataSet不知道表中的外鍵約束,並按字母順序創建表列表。但是,CLEAN_INSERT操作會獲取表的列表並以相反順序遍歷它,並且它要求在引用的實體(此處爲:UserGroup)之前刪除外鍵引用(此處爲ServiceUser.userGroup_id)。

我發現這個信息通過Unitils doesn't workhttp://forum.spring.io/forum/spring-projects/data/12868-dbunit-test-fails-mysql-server-hates-me?p=337672#post337672

一些小挖成的DbUnit文檔導致校正方法來創建數據集,檢查外鍵的依賴,並試圖訂購實體適當:

IDataSet fullDataSet = new FilteredDataSet(new DatabaseSequenceFilter(connection), connection.createDataSet()); 

結果:

<dataset> 
    <administrable/> 
    <usergroup/> 
    <serviceuser/> 
</dataset> 

這將CLEAN_INSERT正確。

聲明:我還沒有遇到循環依賴或自引用外鍵,並且我還沒有測試過此修補程序可以處理它們。

+0

你在哪裏放置代碼片段? – 2015-10-15 09:01:46

+0

我不確定你在問什麼。我沒有提到任何關於代碼片段的內容,所有相關的代碼都可以在問題或答案中找到。 – blagae 2015-10-15 09:48:57

+0

您正在使用的代碼IDataSet片段。你把那個文件放在哪個文件中? – 2015-10-15 10:15:45