开发者

JPA how to remove parent without delete children?

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:

  1. CASCADE: dependent rows get deleted
  2. RESTRICT: delete fails with an error
  3. NO ACTION: like delete, but allows triggers to run first, in case they fix the error
  4. SET NULL: sets the referencing columns to null (at least one column must be nullable)
  5. 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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜