I'm trying to remove a parent, but I keep getting a Foreign Key violation. If I put Cascade.ALL in the parent, it delete the children too. And it's now what I want.
I have my parent class : Docteur
//bi-directional many-to-one association to Patient @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH}, orphanRemoval=false, mappedBy="docteur") private List patients;
and my children are : Patient
I put that
@ManyToOne() private Docteur docteur;
but in my case, the patient choul only ha开发者_JS百科ve one Docteur.
In my Manager class. I try lot of things that didn't work
here my latest 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);
Here the error that I get :
Cannot delete or update a parent row: a foreign key constraint fails (jerabi_asteriskdb/Patient
, CONSTRAINT FK340C82E5A10F077E
FOREIGN KEY (docteur_DOCTEUR_ID
) REFERENCES Docteur
(DOCTEUR_ID
))
You get a foreign key violation because the database checks that every docteur_id in the patient table refers to a valid docteur. This is the whole point of foreign keys. The database ensures that you don't delete a docteur still referenced by patients.
In order to delete your docteur, you must ensure that no other record in the database references this docteur_id. So, you must update all the patients of this docteur and set their docteur_id to 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);
Also, all the attached (persistent) entities are automatically updated by Hibernate. There is no need to persist and merge them. Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-overview.
So that a relation database can enforce data integrity, references to dependent rows in referencing tables have to be considered. SQL 2003 specifies 5 different referential actions:
- CASCADE: dependent rows get deleted
- RESTRICT: delete fails with an error
- NO ACTION: like delete, but allows triggers to run first, in case they fix the error
- SET NULL: sets the referencing columns to null (at least one column must be nullable)
- SET DEFAULT: sets the referencing columns to their default value (which will then reference another existing row in the table, unless at least one default is NULL)
精彩评论