2011-03-13 4 views
2

J'essaie de supprimer un parent, mais je continue d'obtenir une violation de clé étrangère. Si je mets Cascade.ALL dans le parent, il supprime aussi les enfants. Et c'est maintenant ce que je veux.JPA comment faire pour supprimer parent sans supprimer les enfants?

J'ai ma classe parent: Docteur

 
//bi-directional many-to-one association to Patient 
    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH}, orphanRemoval=false, mappedBy="docteur") 
    private List patients; 

et mes enfants sont les suivants: patients

Je mis que

 
    @ManyToOne() 
    private Docteur docteur; 

mais dans mon cas, le choul patient ont seulement un Docteur .

Dans ma classe Manager. J'essaie beaucoup de choses qui ne fonctionne pas

ici ma dernière version

 
Clinique clinique = read(clinique_ID); 
Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult(); 

clinique.getDocteurs().remove(docteur); 

entityManager.merge(clinique); 

entityManager.persist(clinique); 

Voici l'erreur que je reçois:

Impossible de supprimer ou mettre à jour une ligne parent: une contrainte de clé étrangère échoue (jerabi_asteriskdb/Patient, CONTRAINTE FK340C82E5A10F077E FOREIGN KEY (docteur_DOCTEUR_ID) rÉFÉRENCES Docteur (DOCTEUR_ID))

Répondre

0

pour qu'une base de données relationnelle peut appliquer l'intégrité des données, les références à r dépendantes les flux dans les tableaux de référence doivent être pris en compte. SQL 2003 spécifie 5 différentes actions référentielles:

  1. CASCADE: lignes dépendantes sont supprimés
  2. restrict: suppression échoue avec une erreur
  3. NO ACTION: comme supprimer, mais permet de déclencher exécuter d'abord, dans le cas où ils fixent l'erreur
  4. SET NULL: définit les colonnes de référence à null (au moins une colonne doit être nullable)
  5. SET DEFAULT: définit les colonnes de référencement à leur valeur par défaut (qui référencera alors une autre ligne existante dans le tableau, sauf si au moins un par défaut est NULL)
+1

le problème c'est comment faire cela dans JPA 2.0. SQL simple aurait été facile. –

5

Vous obtenez une violation de clé étrangère car la base de données vérifie que chaque docteur_id de la table patient se réfère à un docteur valide. C'est tout le point des clés étrangères. La base de données garantit que vous ne supprimez pas un docteur toujours référencé par les patients.

Afin de supprimer votre docteur, vous devez vous assurer qu'aucun autre enregistrement de la base de données ne fait référence à ce docteur_id. Donc, vous devez mettre à jour tous les patients de cette et définir leur docteur docteur_id null:

Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult(); 

for (Patient patient : docteur.getPatients()) { 
    patient.setDocteur(null); 
} 
docteur.patients.clear(); 
clinique.getDocteurs().remove(docteur); 

En outre, toutes les entités attachées (persistantes) sont mis à jour automatiquement par Hibernate. Il n'y a pas besoin de persister et de les fusionner. Lire http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-overview.

+0

Désolé, je me suis référé à Hibernate, et peut-être que vous utilisez une autre implémentation JPA. La réponse est toujours là. –

+0

Si vous devez explicitement définir les objets Docteur sur null, cela ne va-t-il pas à l'encontre de l'objectif de l'utilisation de JPA pour faire des suppressions de cassade? Si tel est le cas, je pense que l'écriture de mon propre SQL de suppression est meilleure et plus str8 vers l'avant. –

+0

@ Mr.PortStJoe une suppression en cascade supprimerait les patients du docteur lors de la suppression du docteur. L'OP veut supprimer le docteur mais laisse les patients dans la base de données, sans docteur. Il n'y a pas de cascade ici. –

Questions connexes