Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: Foreign key constraint on delete

I have the following relationship

Class UserAccount{
//Other fields
@OneToMany(mappedBy = "userAccount", cascade = CascadeType.REMOVE)
private Set<Images> imagesShared;

@ManyToMany
@JoinTable(name = "USER_LIKES", joinColumns = @JoinColumn(name = "USER_NAME"),   inverseJoinColumns = @JoinColumn(name = "ID"))
private Set<Images> imagesLiked;
}

Class Images{
//other fields
@ManyToMany(mappedBy = "imagesLiked")
private Set<UserAccount> likes;
}

I get an exception after these lines

Hibernate: delete from IMAGES where ID=?
Hibernate: delete from COMMENTS where COMMENT_ID=?
Hibernate: delete from COMMENTS where COMMENT_ID=?
Hibernate: delete from COMMENTS where COMMENT_ID=?
Hibernate: delete from COMMENTS where COMMENT_ID=?
Hibernate: delete from COMMENTS where COMMENT_ID=?
Hibernate: delete from IMAGES where ID=?

Exception:

Cannot delete or update a parent row: a foreign key constraint fails (`testdb`.`USER_LIKES`, CONSTRAINT `FKC6704E28B4E3D8B` FOREIGN KEY (`ID`) REFERENCES `IMAGES` (`ID`))

From my understanding this happens when JPA tries to remove imagesShared. I tried doing this:

for (Images image : userAccount.getImagesShared()){
            image.setLikes(null);
        }
em.remove(account);

But same error. Anyone?

UPDATE

When I add this line it works fine.

 for (Images image : userAccount.getImagesShared()){
            image.setLikes(null);
        }
userAccount.getImagesShared().clear();
em.remove(account);

But what is the difference between the remove operation that JPA does and what I do?

like image 753
shazinltc Avatar asked Mar 25 '23 09:03

shazinltc


1 Answers

One of your private Set<Images> imagesShared or private Set<Images> imagesLiked must have a reference to the Image you are trying to delete.

You will have to loop through everything and remove the image reference before removing it.

EDIT :

To answer your second question.

 for (Images image : userAccount.getImagesShared()){
            image.setLikes(null);
        }
userAccount.getImagesShared().clear();
em.remove(account);

works because you are clearing the image references stored in userAccount by calling userAccount.getImagesShared().clear()

Previously what you were doing was simply removing the likes stored in that Image, not removing the images from the userAccount object itself.

like image 199
Thihara Avatar answered Mar 30 '23 22:03

Thihara