1

I'm working on a java web project that uses:

  • Spring 4.3.2

  • Hibernate 5.2.2/JPA 2.0+ MySQL5InnoDBDialect

  • MySQL 5.6.15-innoDB (on EasyPHP/PHPMyAdmin) + JDBC connector 6.0.4

I'm facing a error when i want to delete some data. But, this problem does exist only if i want to Delete a parent row that have children and one of his children also have at least one child.


Goal: I want the action/query to delete the selected row and its children and grandchildren.


Error code: in server output

28-Sep-2016 11:51:30.345 ERROR [http-nio-80-exec-42] org.hibernate.internal.ExceptionMapperStandardImpl.mapManagedFlushFailure HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement] org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Parent classe: Pavillon

//...
private Set<Table> pavTables;
//...
@JsonIgnore
@Cascade(CascadeType.ALL)
@OneToMany(orphanRemoval = true, mappedBy = "pavillon", fetch = FetchType.EAGER)
public Set<com.optimal.waiter.component.model.Table> getPavTables() {
    return pavTables;
}
//...setters & others

Child classe: Table

//...
private Pavillon pavillon;
//...
@NotNull
@Basic(optional = false)
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PAV_ID")
public Pavillon getPavillon() {
    return pavillon;
}
@JsonIgnore
@Cascade(CascadeType.ALL)
@OneToMany(orphanRemoval = true, mappedBy = "table", fetch = FetchType.EAGER)
public Set<Reservation> getTableReservations() {
    return tableReservations;
}
//...setters & others

Grandchild class: Reservation

//...
private Table table;
//...
@NotNull
@Basic(optional = false)
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TAB_ID", nullable = false)
public Table getTable() {
    return table;
}
//...setters & others

SQL:

CREATE TABLE PAVILLONS
(
   PAV_ID               INT(10) NOT NULL AUTO_INCREMENT,
   PAV_NOM              VARCHAR(25) NOT NULL,
   PAV_DES              TEXT,
   PAV_TYPE             INT(1) NOT NULL DEFAULT 0,
   PRIMARY KEY (PAV_ID)
);
CREATE TABLE TABLES
(
   TAB_ID               INT(10) NOT NULL AUTO_INCREMENT,
   PAV_ID               INT(10) NOT NULL DEFAULT 1,
   TAB_DISPO            TINYINT(1) NOT NULL DEFAULT 1,
   TAB_TYPE             INT(1) NOT NULL DEFAULT 0,
   PRIMARY KEY (TAB_ID)
);
CREATE TABLE RESERVATIONS
(
   RES_ID               INT(10) NOT NULL AUTO_INCREMENT,
   TAB_ID               INT(10) NOT NULL,
   PRIMARY KEY (RES_ID)
);
ALTER TABLE TABLES ADD CONSTRAINT FK_PAV_TAB FOREIGN KEY (PAV_ID)
      REFERENCES PAVILLONS (PAV_ID) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE RESERVATIONS ADD CONSTRAINT FK_TABLE_RESERVATION FOREIGN KEY (TAB_ID)
  REFERENCES TABLES (TAB_ID) ON DELETE CASCADE ON UPDATE CASCADE;

PS: the error still even when i try to delete then using SQL query directly in PHPMyAdmin.

Error code: in server output

ERROR 1451: 1451: Cannot delete or update a parent row: a foreign key constraint fails (commandes, CONSTRAINT FK_TAB_COMM FOREIGN KEY (TAB_ID) REFERENCES tables (TAB_ID)) SQL Statement: DELETE FROM pavillons WHERE PAV_ID='2'

That's why i think the problem is in DB side.

Waiting for your help, any suggestion will help.

5
  • please update your question showing the output of show create table myTable where myTable are at least the ones for the children Commented Sep 28, 2016 at 13:38
  • 1
    I believe you are mixing Hibernate and JPA annotations. I am not sure if this works. Can you try removing Hibernate's Cascade annotation and use @OneToMany as @OneToMany(..., cascade=CascadeType.ALL) - and do note that CascadeType here is javax.persistence.CascadeType! Commented Sep 28, 2016 at 13:51
  • 1
    The foreign key name in the error message is different from the one you used. Is it possible you have multiple FKs defined and one of them does not have the on delete cascade part? Commented Sep 28, 2016 at 14:45
  • @NikosParaskevopoulos i tried it both ways and there's no difference.in addition, if i use javax.persistence.CascadeType there was more unwanted things to set in the DAO. No need for this and it is not the problem in this case. Thanks for your help. Commented Sep 28, 2016 at 15:18
  • @Shadow it could be!!, I have another class named Commande attached with the class Table using @OneToOne relation. it mean conceptually that a Table can have many reservations and a command is setter to one table and the table ID is required on it. I think this is the problem thanks. Commented Sep 28, 2016 at 15:51

2 Answers 2

1

Depending on the comment of @Shadow i I figured that another table/entity related to the grandchild cause this problem.

Any one face this problem in the future, should recheck all relations of each related table.

eg: TableA ---> TableB ---> TableC ---> TableD

To delete a row of TableA (the way i wanted to do - Cascade way), it need to have all the way relations to TableD correctly cascaded ON DELETE CASCADE. specially if all FK are forced NOT NULL.

Sign up to request clarification or add additional context in comments.

Comments

0

It is expected behavior - to not generate orphaned rows. So it is not exactly a problem with the database but a feature of InnoDB engine.

Try to familiarize with InnoDBs Foreign Key Constraints.

3 Comments

Sorry, I don't get your point of view. do you think the data in my DB contains some orphan rows before the delete process?
@MalekBoubakri no, but there would be, if your query would succeed. Thats why it fails.
My fault,!! I do edit my question, please check it again. i forgot to mention my goal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.