Wednesday March 01, 2006
DbUnit Tip: Turn off foreign key constraints when importing into MySQL
One of the issues I've had with using DbUnit is getting tables to load in the proper order from XML. The XML datasets I use to load table data are flat and don't really have any notion of foreign keys and such. Therefore, when you get into a situation where tables have a circular reference, using DbUnit can be a real bitch. I ran into this situation yesterday.
Luckily, I was able to figure out a solution thanks to the help of Mark Matthews. Just add "sessionVariables=FOREIGN_KEY_CHECKS=0" to your JDBC URL. Here's how the "db-load" target in AppFuse looks with this in place:
<target name="db-load" depends="prepare"
description="Loads the database with sample data">
<property name="operation" value="CLEAN_INSERT"/>
<property name="file" value="metadata/sql/sample-data.xml"/>
<dbunit driver="${database.driver_class}"
supportBatchStatement="false"
url="${database.url}&sessionVariables=FOREIGN_KEY_CHECKS=0"
userid="${database.username}" password="${database.password}">
<operation type="${operation}" src="${file}" format="xml" transaction="true"/>
</dbunit>
</target>
Does your preferred database have a similar mechanism for turning off foreign key checks using the connection URL? Posted in Java at Mar 01 2006, 04:16:48 PM MST 15 Comments
Search This Site
Recent Entries
- [OSCON 2008] Even Faster Web Sites by Steve Souders
- [OSCON 2008] CSS for High Performance JavaScript UI by Gavin Doughtie
- [OSCON 2008] The State of Lightning Talks
- [OSCON 2008] Web Frameworks of the Future: Flex, GWT, Grails and Rails
- [OSCON 2008] Caching and Performance: Lessons from Facebook by Lucas Nealan
- [OSCON 2008] Google XML Pages (GXP) by Harry Heymann and Laurence Gonsalves
- [OSCON 2008] An Introduction to Ruby Web Frameworks by Ryan Carmelo Briones
- [OSCON 2008] The Keynote
- GWT and REST
- OSCON: Where are the good parties at?
Posted by Ahmed Mohombe on March 02, 2006 at 06:02 AM MST #
Posted by Paul Devine on March 02, 2006 at 02:57 PM MST #
You can do something similar to the Oracle thing in PostgreSQL, see here . You need to explicitly mark the FKC's as deferrable, I dunno if that's the way Oracle does it.
I just had a John McEnroe moment (ie "you cannot be serious") reading about the MySQL behaviour. From what I can see, the implication is that the checking is completely turned off, not just delayed until the end of the transaction. What happens if the data's bad? It will happily insert your bad data. This seems unspeakably evil to me, although it's generally in line with the MySQL way of doing things. Have I misread?
Posted by Tom Dunstan on March 06, 2006 at 01:27 AM MST #
Posted by Thomas Ramapuram on March 07, 2006 at 10:46 PM MST #
Posted by Matt Raible on March 08, 2006 at 07:12 AM MST #
Posted by Vahan Harput on March 12, 2006 at 12:47 PM MST #
<dbunit driver="${database.driver_class}" supportBatchStatement="false" url="${database.url}?&sessionVariables=FOREIGN_KEY_CHECKS=0" userid="${database.username}" password="${database.password}"> <operation type="${operation}" src="${file}" format="xml" transaction="true"/> </dbunit>Posted by Trenton Lipscomb on April 03, 2006 at 12:05 PM MDT #
Posted by Tom on May 24, 2006 at 10:53 AM MDT #
http://blogs.sourceallies.com/roller/page/joedeveloper?entry=dbunit_ant_task_and_foreign
There's a bit of code, but it will compile against the latest release of DBUnit and allow you to execute a script as part of the ant task. In said script you can utilize the connection that is being used to disable the FKChecking. It was the only way I could get things to work as the above listed method gave me all sorts of fits.
The extension shown also allows other options for use when using DBUnit for pre and post scripting. more concise than a bunch of sql targets IMHO.
Posted by Brian Greene on July 13, 2006 at 09:47 AM MDT #
To Tom:
I also use DbUnit (2.1) programatically. What I've found works (and works pretty well for us) is subclassing DatabaseTestCase and using that for all our MySQL database test cases.
In my getConnection() method, I simply turn off foreign key checking using "SET FOREIGN_KEY_CHECKS=0". This lets DbUnit load my test data with no hiccups.
However, since a) that's a session variable, and b) the actual tests get their own connections directly from the datasource (I use Spring JdbcDaoSupport), then the actual DAO operations execute with foreign key constraint checks on - thus making my tests more robust and in line with the production environment.
Posted by Alistair Israel on September 05, 2006 at 11:20 PM MDT #
Is there a way to include this in Java code rather then specify in the Ant task.
Is there an alternate solution for SQLServer2005?
Following is the code I'm using to load the data into DB from an XML dataset. How do I set the FOREIGN_KEY_CHECKS=0 in the code here ??
// Get the database connection Connection jdbcConnection = dataSource.getConnection(); DatabaseConfig dbConfig = new DatabaseConfig(); dbConfig.setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES,true); IDatabaseConnection connection = new databaseConnection(jdbcConnection,schema); try { //initialize your dataset here IDataSet dataSet = new FlatXmlDataSet(new File(dataSetName)); // This operation decorates an insert operation and disables the MS SQL Server automatic // identifier generation (IDENTITY) during its execution InsertIdentityOperation.CLEAN_INSERT.execute(connection, dataSet); return 1; } catch (Exception ex) { ex.printStackTrace(); throw new ServiceUnavailableException(); } finally { if (connection != null) connection.close(); }Posted by sageer on November 07, 2006 at 07:43 PM MST #
I have tried appending "&sessionVariables=FOREIGN_KEY_CHECKS=0" to my JDBC URL, with no effect, and Alistair's approach sounds better anyway.
Thanks in advance.
--James
Posted by James Adams on December 27, 2006 at 12:02 AM MST #
Posted by Robert Jewett on February 27, 2008 at 08:25 PM MST #
Posted by niko on March 03, 2008 at 06:48 AM MST #
Posted by Paddy Daly on May 19, 2008 at 10:27 AM MDT #