2014-10-13 10 views
5

Ich bin derzeit bemüht, eine Entität zu löschen, die in verschiedenen Beziehungen beteiligt ist (Nur @ManyToOne) - Hibernate löscht jedoch nichts - nach dem Aufruf em.remove bleibt alles unverändert.Hibernate EntityManager: Entfernen referenzierte Entity funktioniert nicht


Ich habe 5 Einheiten (E1 - E5), Verweis auf die Entität (E6) in Frage wie folgt aus:

@Entity 
public class EX { 
    @OneToMany(mappedBy = "eX", fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.REMOVE }) 
    private Set<E6> e6s; 
} 

E6 selbst hat die umgekehrte @ManyToOne Relations:

public class E6{ 

    @ManyToOne(optional = false) 
    private E1 e1;  

    @ManyToOne(optional = false) 
    private E2 e2; 

    @ManyToOne(optional = false) 
    private E3 e3; 

    @ManyToOne(optional = false) 
    private E4 e4; 

    @ManyToOne(optional = false) 
    private E5 e5; 
} 

(links out ids, zusätzliche Spalten etc ...)


Immer wenn ich rufe em.remove(instanceOfE6), einfach nichts geschieht. Ich habe Hibernate SQL-Output hinzugefügt und kann keinen einzigen Versuch sehen, eine DELETE Abfrage auszuführen.

Da die Streichung von einer Ajax-Anforderung und ein frisch EntityManager passieren kann, habe ich einen Anruf vor dem Löschen zu fusionieren, verursache otherwhise Ich erhalte eine Entity nicht verwaltete Ausnahme:

em.remove(em.merge(instanceOfE6)); 

Aber nichts . Staat bleibt unverändert.

Also habe ich versucht, eine @PreRemove Methode, um alle Beziehungen zu löschen, bevor Sie die Entität löschen ... Methode wird nie aufgerufen.

Ich habe verschiedene Cascade-Operationen (einschließlich Cascade.ALL) ausprobiert - aber da alles, was ich brauche, Entfernen und Bleiben ist, sollte das auch funktionieren.


Ich dachte über eine native Delete-Anweisung (jede Einheit hat eine Surrogat-ID, so dass würde höchstwahrscheinliche Arbeit) - aber da alles innerhalb eines AJAX-Aufrufs geschieht, ich will nicht, dass die Verwendung , weil ich den Persistence-Cache aktualisiert haben möchte, ohne jede beteiligte Entität neu zu laden ...

Irgendwelche Ideen?

Wenn Sie mehr Quelle benötigen, schreiben Sie mir einfach einen Kommentar.


Ich habe auch versucht die fragliche Einheit von ALLEN Beziehungen (Objekt-weise) und em.merge() auf einer der verbleibenden Einheiten rufen zu entfernen, in der Hoffnung, Hibernate die unverbundenen Unternehmen whipe - kein Glück.

+1

Haben Sie die Transaktion abgeschlossen? –

+0

Haben Sie 'em.flush()' aufgerufen? – jmvivo

+0

@DavidLevesque Running Hibernate im Autocommit-Modus ... – dognose

Antwort

13

dachte ich, das Problem (e) - Ist es zwei von ihnen gewesen: (dies hier Weggehen, wenn jemand über ein ähnliches Problem stolpert)

Wie bereits erwähnt, hat die Streichung in einer Ajax geschehen sollte anfordern. Daher ist ein einfacher Aufruf

em.remove(instanceOfE6); 

führte zu einer java.lang.IllegalArgumentException: Removing a detached instance Ausnahme.Also, ich versuchte den Ansatz mit merge:

em.remove(em.merge(instanceOfE6)); 

die keinen Fehler erzeugt - aber einfach hat nicht funktioniert. Ich aktivierte Trace-Protokollierung für Hibernate, wie in diesem Beitrag erwähnt:

TRACE [org...DefaultPersistEventListener] un-scheduling entity deletion ... 

Offensichtlich hat das Unternehmen noch an anderen Einheiten verbunden zu entfernen: JPA/Hibernate remove entity sometimes not working, um herauszufinden, was schief gelaufen ist, und in der Tat versucht, die Einheit in Folge zu entfernen , was zu dem Problem führte, dass Hibernate die Löschung abbrach, also versuchte ich, die Beziehungen vor dem Löschen zu entfernen. Wie Sie aus dem Beispiel von E6 sehen können, habe ich @ManyToOne(optional = false) verwendet, was bedeutet, dass ich die ausgehenden Verweise nicht auf null setzen kann oder Ausnahmen beim Aufruf von merge verursacht.

Mein erster Versuch, die Beziehungen zu bereinigen, war nur "die Sätze zu bereinigen", weil ich annahm, dass das Reinigen der ausgehenden Beziehungen der Entität, die ich löschen möchte, nicht erforderlich ist. Es ist nicht, aber ich werde dies ein wenig später im Detail skizzieren:

So, jetzt der Code sah aus wie

instanceOfE6.getE1().getE6s().remove(instanceOfE6); 
instanceOfE6.getE2().getE6s().remove(instanceOfE6); 
instanceOfE6.getE3().getE6s().remove(instanceOfE6); 
instanceOfE6.getE4().getE6s().remove(instanceOfE6); 
instanceOfE6.getE5().getE6s().remove(instanceOfE6); 

em.remove(em.merge(instanceOfE6)); 

gleiche Problem: Löschen abgebrochen. Ich habe die offensichtliche Tatsache übersehen, dass merge Anruf von occ. Stellen Sie die Einträge innerhalb der soeben entfernten Sätze wieder her, da instanceOfE6 NOCH noch keine NULL-Referenzen auf die anderen Entitäten haben konnten. Daher wurde die Löschung erneut abgebrochen.

Schließlich ist die Lösung vonc. die die Zusammenführung zu tun war, bevor die Referenzen und die endgültige Löschung entfernen:

if (!em.contains(instanceOfE6)){ 
    instanceOfE6 = em.merge(instanceOfE6); 
} 

instanceOfE6.getE1().getE6s().remove(instanceOfE6); 
instanceOfE6.getE2().getE6s().remove(instanceOfE6); 
instanceOfE6.getE3().getE6s().remove(instanceOfE6); 
instanceOfE6.getE4().getE6s().remove(instanceOfE6); 
instanceOfE6.getE5().getE6s().remove(instanceOfE6); 

em.remove(instanceOfE6); 

Ich bin nicht ganz sicher, ob ich alles 100% ig genau erklärt, aber zumindest kann ich reproduzieren und beheben das Problem, indem Ändern des Codes hin und her.

+2

Du bist ein Lebensretter. Habe mich zwei Stunden lang mit diesem Problem herumgeschlagen. Vielen Dank. Leute, pass auf Entity Trees auf (ich musste groupToRemove.getParent() schreiben. GetSubgroups(). Remove (groupToRemove) und musste parent mit cascade = CascadeType.MERGE) abbilden. Prost – jpangamarca

+1

'groupToRemove.getParent(). GetSubgroups(). Remove (groupToRemov e)' das ist genau das, was ich getan habe. Es sieht verdammt komisch aus ... aber reinkommen: Es ist logisch :-) – dognose

Verwandte Themen