I got a really brutal looking error message from Spring and MySQL yesterday. I've been working on a Java-based web interface for Nagios for a client, and I ran into an error message that basically says "Cannot add or update a child row: a foreign key constraint fails". If you like ugly, gruesome error messages here is the full-blown error:
INFO: SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase] ***NHTD::insertHostContacts, RuntimeException occurred, message follows. org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO host_contacts (host_id,contact_id,updated_by_id) VALUES (?,?,?)]; Cannot add or update a child row: a foreign key constraint fails (`webapp/host_contacts`, CONSTRAINT `host_contacts_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE CASCADE); nested exception is com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`webapp/host_contacts`, CONSTRAINT `host_contacts_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE CASCADE) *** threw an exception trying to insert a Host PreparedStatementCallback; SQL [INSERT INTO host_contacts (host_id,contact_id,updated_by_id) VALUES (?,?,?)]; Cannot add or update a child row: a foreign key constraint fails (`webapp/host_contacts`, CONSTRAINT `host_contacts_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE CASCADE); nested exception is com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`webapp/host_contacts`, CONSTRAINT `host_contacts_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE CASCADE) rolling back the transaction
My question after seeing this error message is "How can I tell what the constraint 'host_contacts_ibfk_2' refers to?" I can go back to my DDL, but since I already have a MySQL command-line connection open isn't there some way I can run a MySQL command/query to show what that constraint is?
After a little research it seems like the best way to show a constraint like this from the MySQL command line tool is to run a query like this:
show create table host_contacts
(I could tell from the MySQL error message that the problem was with my table named host_contacts
, so that's why I ran the show create table
command on that table.) The output from that MySQL command looks like this:
host_contacts | CREATE TABLE `host_contacts` ( `id` int(11) NOT NULL auto_increment, `host_id` int(11) NOT NULL, `contact_id` int(11) NOT NULL, `updated_by_id` int(11) default NULL, `updated_time` timestamp NOT NULL default CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_host_contacts_unique` (`host_id`,`contact_id`), KEY `updated_by_id` (`updated_by_id`), KEY `contact_id` (`contact_id`), CONSTRAINT `host_contacts_ibfk_1` FOREIGN KEY (`updated_by_id`) REFERENCES `users` (`id`) ON DELETE SET NULL, CONSTRAINT `host_contacts_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE CASCADE, CONSTRAINT `host_contacts_ibfk_3` FOREIGN KEY (`contact_id`) REFERENCES `contacts` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1 |
As you can see, part of the output includes the CONSTRAINT definitions for the table in question. Now I can go back to my error message and realize that the constraint 'host_contacts_ibfk_2' is the host_id
that references the hosts
table, and resolve my problem.