2014-09-30 14 views
5

Ich frage und beantworte diese Frage für zukünftige Referenz, weil ich denke, ich habe eine anständige Lösung für ein häufiges Problem mit DbUnit gefunden. Ich hoffe, es hilft jemandem, irgendwo auf der ganzen Linie.DbUnit kann nicht clean-einfügen: Fremdschlüssel-Constraint

Ich verwende DbUnit 2.5.0 und TestNG 6.8.8. Mein Anwendungsfall ist für einen Teil einer Datenbank, die 3 Entitäten umfasst. Es gibt einen ServiceUser, der einen Fremdschlüssel sowohl für einen Administrable als auch einen UserGroup enthält.

folgte ich den größten Teil des Codebeispiel aus 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(); 
    } 
} 

Das Ergebnis davon wird die folgende XMLDataSet (Daten weggelassen):

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

Wenn TestNG die @AfterMethod ausführt, erhalte ich die folgende Ausnahme:

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`)) 

Antwort

11

Das Problem ist, dass das XMLDataSet, das ich oben erstellte, die Fremdschlüsseleinschränkungen in den Tabellen nicht kennt und die Tabellenliste alphabetisch erstellt. Die Operation CLEAN_INSERT übernimmt jedoch die Liste der Tabellen und durchläuft sie in umgekehrter Reihenfolge. Dazu müssen die Fremdschlüsselreferenzen (hier: ServiceUser.userGroup_id) vor der referenzierten Entität gelöscht werden (hier: UserGroup).

fand ich diese Informationen durch Unitils doesn't work und http://forum.spring.io/forum/spring-projects/data/12868-dbunit-test-fails-mysql-server-hates-me?p=337672#post337672

Einige kleinere Graben in die DbUnit Dokumentation zum Erstellen des Datensatzes zu einem korrigierten Ansatz geführt, die für Fremdschlüsselbeziehungen überprüft und versucht, die Entitäten in geeigneter Weise zu bestellen:

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

Ergebnis:

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

Dies wird CLEAN_INSERT korrekt.

Haftungsausschluss: Ich bin nicht auf zirkuläre Abhängigkeiten oder auf sich selbst verweisende Fremdschlüssel gestoßen, und ich habe nicht getestet, dass dieser Fix mit ihnen umgehen kann.

+0

Wo haben Sie das Code-Snippet platziert? –

+0

Ich bin mir nicht sicher, was Sie fragen. Ich sage nichts über ein Code-Snippet und der gesamte relevante Code ist entweder in der Frage oder in der Antwort verfügbar. – blagae

+0

Der Code IDataSet Snippet, den Sie verwendet haben. In welche Datei hast du das gelegt? –

Verwandte Themen