2014-09-30 11 views
5

Pytam i odpowiadam na to pytanie do przyszłego użytku, ponieważ uważam, że znalazłem przyzwoite rozwiązanie typowego problemu z DbUnit. Mam nadzieję, że pomaga komuś, gdzieś w dole.DbUnit nie może wyczyścić-wstawić: ograniczenie klucza obcego

Używam DbUnit 2.5.0 i TestNG 6.8.8. Mój przypadek użycia dotyczy części bazy danych, która obejmuje 3 podmioty. Istnieje ServiceUser, który zawiera klucz obcy zarówno dla Administrable i UserGroup.

Śledziłem większość przykład kodu z 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(); 
    } 
} 

Wynikiem tego jest następujący XMLDataSet (dane pominięta):

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

Kiedy TestNG wykonuje @AfterMethod, pojawia się następujący Wyjątek:

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

Odpowiedz

11

Problem polega na tym, że utworzony powyżej XMLDataSet nie zna ograniczeń klucza obcego w tabelach i tworzy listę alfabetyczną. Operacja CLEAN_INSERT pobiera listę tabel i wykonuje ją w odwrotnej kolejności i wymaga, aby odwołania do kluczy obcych (tutaj: ServiceUser.userGroup_id) zostały usunięte przed odwołanym obiektem (tutaj: UserGroup).

znalazłem tej informacji za pośrednictwem Unitils doesn't work i http://forum.spring.io/forum/spring-projects/data/12868-dbunit-test-fails-mysql-server-hates-me?p=337672#post337672

Niektóre drobne kopanie w dokumentacji DBUnit doprowadziło do poprawionego podejścia do tworzenia zbioru danych, który sprawdza zagranicznych kluczowych zależnościach i próbuje zamówić podmioty odpowiednio:

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

Wynik:

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

Ta wola CLEAN_INSERT poprawnie.

Zastrzeżenie: Nie natknąłem się na zależności cykliczne lub własne klucze obce i nie przetestowałem, czy ta poprawka może sobie z nimi poradzić.

+0

Gdzie umieściłeś fragment kodu? –

+0

Nie jestem pewien, o co pytasz. Nie mówię nic o fragmencie kodu, a cały odpowiedni kod jest dostępny w pytaniu lub odpowiedzi. – blagae

+0

Fragment kodu kodu IDataSet, z którego korzystałeś. W jakim pliku to umieściłeś? –

Powiązane problemy