java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (hrms.employees, CONSTRAINT FKe4i9i8vu1j96m71g4v98kqirb FOREIGN KEY (designation_id) REFERENCES designations (id))
I just land on this problem, I try to delete an entity, but the entity have a relation with another entity and another entity have another relation to imagine the picture this is the tables
How to detach employee and designation from department when I want to delete department. I can delete designations in the code, but I don't want to delete the employee with foreign key associated to the department and designation.
CREATE TABLE `departments` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
CREATE TABLE `designations` (
`id` bigint NOT NULL AUTO_INCREMENT,
`department_name` varchar(40) DEFAULT NULL,
`name` varchar(140) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
CREATE TABLE `employees` (
`id` bigint NOT NULL AUTO_INCREMENT,
`address` varchar(255) NOT NULL,
`dob` varchar(255) DEFAULT NULL,
`email` varchar(35) NOT NULL,
`employee_number` varchar(255) NOT NULL,
`first_name` varchar(40) NOT NULL,
`full_name` varchar(100) NOT NULL,
`gender` varchar(255) DEFAULT NULL,
`join_date` varchar(255) NOT NULL,
`last_name` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
`phone_number` varchar(255) NOT NULL,
`username` varchar(255) NOT NULL,
`department_id` bigint DEFAULT NULL,
`designation_id` bigint DEFAULT NULL,
`avatar_image` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKgy4qe3dnqrm3ktd76sxp7n4c2` (`department_id`),
KEY `FKe4i9i8vu1j96m71g4v98kqirb` (`designation_id`),
CONSTRAINT `FKe4i9i8vu1j96m71g4v98kqirb`
FOREIGN KEY (`designation_id`)
REFERENCES `designations` (`id`),
CONSTRAINT `FKgy4qe3dnqrm3ktd76sxp7n4c2`
FOREIGN KEY (`department_id`)
REFERENCES `departments` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Spring is completely irrelevant to your question. Its all about the MySQL database and the way you have defined the tables in your DDL.
You cannot delete a Parent row if a Child row exists on your database because of how you defined that constraint.
There is a ON DELETE .... syntax which tells MySQL what to do when a parent row is deleted, by default MySQL will reject the delete, you can change this in a number of ways, as specified in the MySQL manual, of all the odd places.
In your case as you want to NOT DELETE the Employee when you delete the Department, and you have the column
`department_id` bigint DEFAULT NULL,
defined as DEFAULT NULL then change your CONSTRAINT as below
CONSTRAINT `FKgy4qe3dnqrm3ktd76sxp7n4c2`
FOREIGN KEY (`department_id`)
REFERENCES `departments` (`id`)
ON DELETE SET NULL
You could of course also do
CONSTRAINT `FKgy4qe3dnqrm3ktd76sxp7n4c2`
FOREIGN KEY (`department_id`)
REFERENCES `departments` (`id`)
ON DELETE SET DEFAULT
both would do the same thing in this case as your default is NULL for that column
Related
I have table relation like this scenario -> event -> plan and they are:
scenario_table:
CREATE TABLE `scenario` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`plan_cycle_id` bigint(20) unsigned NOT NULL,
`created_by` varchar(255) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `scenario_table_plan_cycle_id_fk` (`plan_cycle_id`),
CONSTRAINT `scenario_table_plan_cycle_id_fk` FOREIGN KEY (`plan_cycle_id`) REFERENCES `planning_cycle` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
event_table
CREATE TABLE `event` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`start_date` timestamp NULL DEFAULT NULL,
`end_date` timestamp NULL DEFAULT NULL,
`scenario_id` bigint(20) unsigned NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_by` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_scenario_id` (`scenario_id`),
CONSTRAINT `fk_scenario_id` FOREIGN KEY (`scenario_id`) REFERENCES `scenario` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
plan_table
CREATE TABLE `plan` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`scenario_id` bigint(20) unsigned NOT NULL,
`input` json DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_by` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `plan_scenario_id` (`scenario_id`),
CONSTRAINT `FKnjhfw18pms9j2yhtvu954hcsi` FOREIGN KEY (`scenario_id`) REFERENCES `scenario` (`id`), // this was not there in create table command but later added by mysql //
CONSTRAINT `plan_scenario_id` FOREIGN KEY (`scenario_id`) REFERENCES `event` (`scenario_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
Now I want to cascade delete scenario, event and plan for some particular scenario_id. When there are no grandchildren, scenario and event are getting deleter as expected. But when a new entry is present in plan which refers a scenario_id, am getting this error while deletion:
java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`db_dev`.`plan`, CONSTRAINT `plan_scenario_id` FOREIGN KEY (`scenario_id`) REFERENCES `event` (`scenario_id`))
I tried EAGER loading in eventEntity.java like this:
#OneToMany(fetch = FetchType.EAGER, mappedBy = "scenario", cascade = CascadeType.ALL)
private List<planEntity> planEntityList;
and in planEntity.java like this:
#ManyToOne
#JoinColumn(name = "scenario_id", referencedColumnName = "id")
private ScenarioEntity scenario;
How I can handle this case through *entity.java files ?
In MySql when a table is InnoDB you can Add Foreign Key Constraints. Foreign Key checks is done when you update or delete a record. The results of foreign Key checks depend on the design of your table as you may allow cascading the update or delete or prevent the process of update or delete.
The following is an example of a parent:
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Example of child table that allows parent table to delete or update the (id) field of the parent table (Child also will be deleted):
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB;
Example of child table that prevents the update of (id) field of parent but allows parent table to be deleted. (Child also will be deleted):
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON DELETE CASCADE
) ENGINE=INNODB;
Example of child table that prevents parent table to delete or update the (id) field of the parent table. This will give error like "Cannot Delete or Update a Parent Row: A Foreign Key Constraint Fails":
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
) ENGINE=INNODB;
You have four options when using foreign key constraints :
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
RESTRICT : is the default if you don't include ON UPDATE/ON DELETE
CASCADE : Delete child when delete parent or update parent_id when id of parent changed.
for more information you can see FOREIGN KEY Constraints
There is also a variable that control foreign key checks. If you set it to 0 (false) you will disable foreign key checks.
SET FOREIGN_KEY_CHECKS=0;
Back to your database, I think it is better to modify your tables structure to allow cascade delete. You can also use ON DELETE SET NULL then later you can delete any record where parent_id=null. If you can't modify tables structure then you have to first delete records in child table before deleting parent record.
I am running this Query on MySQL workbench with the latest version of MySQL installed on MacOS.
My SQL Query is:
CREATE DATABASE IF NOT EXISTS `imdb`;
USE `imdb`;
DROP TABLE IF EXISTS `rating`;
DROP TABLE IF EXISTS `media`;
CREATE TABLE `media` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(70) DEFAULT NULL,
`year` varchar(70) DEFAULT NULL,
`rated` varchar(70) DEFAULT NULL,
`released` varchar(70) DEFAULT NULL,
`runtime` varchar(70) DEFAULT NULL,
`genre` varchar(70) DEFAULT NULL,
`director` varchar(70) DEFAULT NULL,
`writer` varchar(70) DEFAULT NULL,
`actors` varchar(70) DEFAULT NULL,
`plot` varchar(7000) DEFAULT NULL,
`language` varchar(70) DEFAULT NULL,
`country` varchar(70) DEFAULT NULL,
`awards` varchar(70) DEFAULT NULL,
`poster` varchar(270) DEFAULT NULL,
`metascore` varchar(70) DEFAULT NULL,
`imdb_rating` varchar(70) DEFAULT NULL,
`imdb_votes` varchar(70) DEFAULT NULL,
`imdb_id` varchar(70) NOT NULL,
`type` varchar(70) DEFAULT NULL,
`dvd` varchar(70) DEFAULT NULL,
`box_office` varchar(70) DEFAULT NULL,
`production` varchar(70) DEFAULT NULL,
`website` varchar(70) DEFAULT NULL,
`response` varchar(70) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `rating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source` varchar(70) DEFAULT NULL,
`value` varchar(70) DEFAULT NULL,
`imdb_id` varchar(70) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`imdb_id`)
REFERENCES `media`(`imdb_id`)
ON DELETE SET NULL
);
SET FOREIGN_KEY_CHECKS = 1;
The create Query on table rating is failing. I don't know why, any help would be appreciated.
The exact error response is:
10:12:44
CREATE TABLE `rating` ( `id` int(11) NOT NULL AUTO_INCREMENT, `source` varchar(70) DEFAULT NULL, `value` varchar(70) DEFAULT NULL, `imdb_id` varchar(70) NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`imdb_id`) REFERENCES `media`(`imdb_id`) ON DELETE SET NULL )
Error Code: 1215.
Cannot add foreign key constraint
0.123 sec
I am building a Spring REST application that uses one too many relationships for building a local copy of the IMDB database or something similar.
A foreign key in MySQL doesn't actually have to reference a primary key column, but it does have to reference a column which is unique. So, one possible fix here would be to add a unique constraint on the imdb_id column:
ALTER TABLE media ADD CONSTRAINT cstr_imdb UNIQUE (imdb_id);
A foreign key is a column or group of columns in a relational database table that provides a link between data in two tables. It acts as a cross-reference between tables because it references the primary key of another table, thereby establishing a link between them.
'id' is the primary key in your table 'media' and not 'imdb_id'. Hence, you can't make a reference to 'imdb_id'.
imdb_id is not a key on the media table - foreign keys must reference keys (or, at least, unique constraints). If imdb_id on the media table should be unique, then you could put a UNIQUE CONSTRAINT on it and will be able to reference it with a foreign key.
Also, you have on delete set null on a column that cannot be null
I am developing a sample project between users and products. A user can sell multiple products and a product can be sold by multiple users. So I designed my db with a many to many relationship. Below are my tables:
create table `users` (
`id` bigint(20) not null auto_increment,
`first_name` varchar(100) not null,
`last_name` varchar(100) not null,
`email` varchar(100) not null,
`password` varchar(255) not null,
`phone_number` varchar(20),
`created_at` timestamp default CURRENT_TIMESTAMP,
`updated_at` timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
primary key(`id`),
unique(`email`)
);
create table `products` (
`id` bigint(20) not null auto_increment,
`name` varchar(255) not null,
primary key(`id`),
unique(`name`)
);
create table `users_products` (
`user_id` bigint(20) not null,
`product_id` bigint(20) not null,
`quantity`int not null,
`price` DECIMAL(5, 2) not null,
`description` text not null,
`created_at` timestamp default current_timestamp,
`updated_at` timestamp default current_timestamp on update current_timestamp,
primary key (`user_id`, `product_id`),
foreign key(`user_id`) references `users`(`id`) on delete cascade,
foreign key(`product_id`) references `products`(`id`) on delete restrict
);
As you can see above, the products table name is unique because users can sell the same products.
Now I ask the question how this can be achieved using spring boot with JPA. I have seen tutorials with many to many with extra columns but the tutorials have just had an extra column with date time. But I want to perssit with the extra columns as mentioned above in the users_products table.
And also is the schema designed ok?
I have two tables
CREATE TABLE `cb_jobs` (
`JOB_IDENTIFIER` INT(11) NOT NULL,
`CB_CREDENTIAL_TYPE_IDENTIFIER` INT(11) NOT NULL
`IS_DELETED` TINYINT(1) NULL DEFAULT '0',
PRIMARY KEY (`JOB_IDENTIFIER`),
INDEX `FK_cb_jobs_cb_credential_type` (`CB_CREDENTIAL_TYPE_IDENTIFIER`)
CONSTRAINT `FK_cb_jobs_cb_credential_type` FOREIGN KEY (`CB_CREDENTIAL_TYPE_IDENTIFIER`) REFERENCES `cb_credential_type` (`CB_CREDENTIAL_TYPE_IDENTIFIER`) ON UPDATE CASCADE ON DELETECASCADE)COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
CREATE TABLE `cb_credential_type` (
`CB_CREDENTIAL_TYPE_IDENTIFIER` INT(11) NOT NULL AUTO_INCREMENT,
`CB_CREDENTIAL_CODE` VARCHAR(50) NULL DEFAULT NULL,
`CB_CREDENTIAL_TYPE_NAME` VARCHAR(1000) NULL DEFAULT NULL,
`CREATED_DATE` DATETIME NULL DEFAULT NULL,
`CREATED_BY_USER` INT(11) NULL DEFAULT NULL,
`UPDATED_DATE` DATETIME NULL DEFAULT NULL,
`UPDATED_BY_USER` INT(11) NULL DEFAULT NULL,
`IS_DELETED` TINYINT(1) NULL DEFAULT '0',
PRIMARY KEY (`CB_CREDENTIAL_TYPE_IDENTIFIER`)
)COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=8;
I would like to get the details of 2nd table based on the credential type id.
How to write Hibernate mapping classes with one to one relationship using hibernate annotations.Anybody please help me.......
Check this tutorial this might help you
http://www.dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-one-to-one-1.html
check the hibernate one-one annotated tutorial
http://www.dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-one-to-one-using-annotations-1.html
I have a table which has a field ID as a primary key and another field PID as the Foreign Key to the ID Field. Both are of long DataTypes.
So this is my table struct
CREATE TABLE `myobj` (
`ID` BIGINT(100) NOT NULL AUTO_INCREMENT,
`FRIENDLY_NAME` VARCHAR(100) DEFAULT NULL,
`PARENT_ID` BIGINT(100) DEFAULT NULL,
`PARENT` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `PARENT_ID` (`PARENT_ID`),
CONSTRAINT `myobj_ibfk_1` FOREIGN KEY (`PARENT_ID`) REFERENCES `myobj` (`ID`) ON DELETE CASCADE
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
I use Hibernate as ORM to insert into the MySQL DB. The problem is
When One or more of the records which will be top level with no parent id, an error occurs with insert top-level records. It looks like in case of no parent id
it will accept only NULL.
But from Java Application code perspective, the datatype is long and hence when i insert an object through Hibernate, with default value as 0 ,it looks like a constraint violation
Cannot add or update a child row: a
foreign key constraint fails
(genericdb.myobj, CONSTRAINT
myobj_ibfk_1 FOREIGN KEY
(PARENT_ID) REFERENCES myobj
(ID) ON DELETE CASCADE)
This problem occurs also when setting 0 as the value thru sql CLI.
Second Secnario:
Also tried setting the Default Value for PARENT_ID as 0.
CREATE TABLE `myobj` (
`ID` BIGINT(100) NOT NULL AUTO_INCREMENT,
`FRIENDLY_NAME` VARCHAR(100) DEFAULT NULL,
`PARENT_ID` BIGINT(100) DEFAULT '0',
`PARENT` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `PARENT_ID` (`PARENT_ID`),
CONSTRAINT `myobj_ibfk_1` FOREIGN KEY (`PARENT_ID`) REFERENCES `myobj` (`ID`) ON DELETE CASCADE
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
SO when i insert 0 into Parent_ID field, still error
Cannot add or update a child row: a
foreign key constraint fails
(genericdb.myobj, CONSTRAINT
myobj_ibfk_1 FOREIGN KEY
(PARENT_ID) REFERENCES myobj
(ID) ON DELETE CASCADE)
Kindly let me know if anything is wrong here.
The problem is that you're trying to point to row in myobj with the id 0, which doesn't exist. The default for that column should be null.
I'm quite sure that if you run select * from myobj where id = 0, you won't get any results back.