4 votes

JPA : Contrainte de clé étrangère sur la suppression

J'ai la relation suivante

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;
}

J'obtiens une exception après ces lignes

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`))

D'après ce que j'ai compris, cela se produit lorsque JPA essaie de supprimer imagesShared . J'ai essayé de faire ça :

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

Mais même erreur. Quelqu'un ?

UPDATE

Lorsque j'ajoute cette ligne, tout fonctionne bien.

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

Mais quelle est la différence entre l'opération de suppression que JPA effectue et ce que je fais ?

6voto

Thihara Points 3969

Un de vos private Set<Images> imagesShared o private Set<Images> imagesLiked doit avoir une référence à l'image que vous essayez de supprimer.

Vous devrez tout parcourir en boucle et supprimer la référence de l'image avant de la supprimer.

EDIT :

Pour répondre à votre deuxième question.

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

fonctionne parce que vous effacez les références de l'image stockées dans userAccount en appelant userAccount.getImagesShared().clear()

Auparavant, ce que vous faisiez était simplement de supprimer les goûts stockés dans cette image, et non de supprimer les images de la base de données. userAccount l'objet lui-même.

1voto

Lakshmi Points 929

Le site private Set<Images> imagesLiked a une référence de clé étrangère au IMAGES ( ID ), donc si vous essayez de supprimer le private Set<Images> imagesShared; sans supprimer le private Set<Images> imagesLiked; .

Essayez donc de supprimer les imagesLien externe également

image.setImagesLinked(null);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X