PostgreSQL JPA - Löschen und orphanRemoval

rmacher01

Mitglied
Habe zwei folgende Entity-Klassen:

@Entity
public class Person {

@OneToOne
private Abteilung abteilung;

}

@Entity
public class Abteilung {

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true)
private List<Person> mitearbeiterListe;
}

Wenn ich versuche, eine Abteilung zu löschen, bekomme ich die Meldung, das FK aus der Tabelle 'person' auf die Abteilung, die gelöscht werden soll, immer noch verweist.

public void deleteAbteilung(Abteilung a) {

// in Kurzform ...

EntityMangaer em = ...

em.getTransaction().begin();

if (!em.contains(abteilung)){

abteilung = em.merge(abteilung);
}

em.remove(abteilung)

em.getTransaction().commit();
}

Fehlermeldung:
Caused by: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „peson“ verletzt Fremdschlüssel-Constraint „fk_peson_abteilung_id“ von Tabelle „person“
Detail: Auf Schlüssel (id)=(20170) wird noch aus Tabelle „person“ verwiesen.


Irgendwie komme ich nicht weiter, denn auch cascade=CascadeType.REMOVE hat nicht geholfen. Wie löscht man so etwas (bidirektionale Association)?

(arbeite mit PostgreSQL und eclipselink)

Zusatzinfos:
  • Die Person ist an sich ein Angestelter und muss eine Abteilung-Referenz haben, während die Abteilung auch ohne Personen (Mitarbeiter) existieren kann.
  • Habe auch versucht, zuerst die Person-Instanzen aus der Liste zu löschen und erst dann die Abteilung, hat nicht geklapt (alles in einer Transaktion)
  • Das Löschen muss in einer Transaktion erfolgen, um im Falle dass es nicht klappt, ein rollback machen zu können.

Danke
 
Zuletzt bearbeitet:

stg

Top Contributor
Zuerst einmal finde ich es fragwürdig, dass Personen gelöscht werden, nur weil die Abteilung gelöscht wird. Aber gut, dafür magst du Gründe haben.

Stutzig macht mich zuerst einmal, dass du manuell eine Transaction startest. In welchem Umfeld führst du den Code aus?

Einfach die Liste leeren, bevor du die Abteilung löschst, sollte bereits ausreichen.
 

rmacher01

Mitglied
Zuerst einmal finde ich es fragwürdig, dass Personen gelöscht werden, nur weil die Abteilung gelöscht wird. Aber gut, dafür magst du Gründe haben.

Stutzig macht mich zuerst einmal, dass du manuell eine Transaction startest. In welchem Umfeld führst du den Code aus?

Einfach die Liste leeren, bevor du die Abteilung löschst, sollte bereits ausreichen.

Zuerst einmal vielen Dank.

Nun, ich arbeite mit Tomcat und dazu noch ist die Ausgangslage in der Tat noch etwas komplizierter. Die obigen Entities sind an sich nur als Stellvertretter gedacht.

Zur Ausgangslage:

Es gebe noch die Entity "Raum" und eine Abteilung belegt mehrere Räume, ein Raum gehört immer nur einer Abteilung.

@Entity
public class Raum{

@OneToOne
private Abteilung abteilung;

}


Dazu noch kommt in die Klasse Abteilung eine wietere Liste für Räume:

@Entity
public class Abteilung {

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true)
private List<Person> mitearbeiterListe;

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true)
private List<Raum> raumListe;
}

Wenn eine Abteilung gelöscht wird, müssen auch alle Räume gelöscht werden, die von dieser Abteilung belegt werden (macht zwar in der Realität keinen Sinn, bei der echten Entity ist es aber so).

Kurz gesagt: wenn eine Abteilung gelöscht wird, müssen alle Personen und Räume gelöscht werden, und dass alles in einer Transaktion (um rollback zu ermöglichen).

Ich habe herausgefunden, dass das Problem von der Bidirektionalität kommt. Wenn die Abteilung weben 'orphanRemoval' versucht, eine Person zu löschen, wird wegen der Referenz Person --> Abteilung versucht, die Abteilung zu löschen. Dies geht aber nicht, da es Räume gibt, die auf die Abteilung verweisen. Aus diesem Grund kann das nicht in einer Transaktion gelöscht werden: so stelle ich es mir vor.

Fall 1: Abteilung hat nur Personen aber keine Räume: Löschen funktioneirt
Fall 2: Abteilung hat nur Räume und keine Personen: Löschen funktioniert
Fall 3: Abteilung hat sowohl Personen als auch Räume: Löschen funktioniert nicht

Vorübergehende Lösung:
  • die Referenzen auf Abteilung in Person und Raum können Null sein
  • in einer ersten Transaktion werden diese Referenzen auf Null gesetzt und die dazugehörigen Personen und Räume updatet (commit inklusive)
  • in einer zweiten Transaktion wird die Abteilung gelöscht
So funktioniert es, allerdings kann ich im Fall, dass die zweite Transaktion misslingt, keinen echten Rollback machen. Da es sich aber um nur zwei Referenzen handelt, wird (zurzeit) in die Logdatei das Nötige geschrieben so das man im Notfall es von Hand noch anpassen kann (die Wahrscheinlichkeit, dass so was passiert ist eher sehr gering).

So sieht meine jetzige Lösung aus. Wenn es da bessere Möglichkeiten gebe, wäre ich um jeden Hinweis sehr froh.
 

stg

Top Contributor
Du hast im hier geposteten Code nirgends ein bidirectionales Mapping, ich hoffe das ist dir klar?!
 

rmacher01

Mitglied
Du hast im hier geposteten Code nirgends ein bidirectionales Mapping, ich hoffe das ist dir klar?!

Das ist korrekt: Die echten bidirektionalen Assoziationen gibt es in der Tat nicht. Mit "Bidirektionalität" habe ich (vielleicht etwas unglücklich) die Tatsache gemeint, dass z.B. eine Abteilung Referenzen auf eine oder mehrere Personen hat, wobei diese wiederum auf die Abteilung je eine Referenz haben (dito mit Räumen). Das Problem kommt vermutlicht dacher, dass diese gerade zweimal vorkommt: einmal mit Personen und einmal mit Räumen.
 

stg

Top Contributor
Du schreibst ziemlich unverständlich. Obendrein postest du nur unvollständigen Code, der ja offenbar dein Problem gar nicht so genau widerspiegelt. Da ist es nicht leicht dir zu helfen ._.
 

rmacher01

Mitglied
Du schreibst ziemlich unverständlich. Obendrein postest du nur unvollständigen Code, der ja offenbar dein Problem gar nicht so genau widerspiegelt. Da ist es nicht leicht dir zu helfen ._.

Sorry (habe am Anfang selbst nicht realisiert, dass das Problem möglicherweise wo anders liegt). Falls möglich, diesen Thread am besten löschen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S gesamte Tabelle löschen Datenbankprogrammierung 2
F SQLite Datensatz löschen Datenbankprogrammierung 13
B Mit Button einen Datensatz löschen Datenbankprogrammierung 2
A Eine MySQL Zeile mit JDBC löschen Datenbankprogrammierung 5
B Fortlaufende Nummer - Was tun bei löschen? Datenbankprogrammierung 6
R eclipselink - referenzierte Entity löschen Datenbankprogrammierung 0
P Indizes / Fremdschlüssel löschen Datenbankprogrammierung 2
H Oracle Aus Datenbank löschen Datenbankprogrammierung 6
P Mit Hibernate mehrere Datensätze löschen Datenbankprogrammierung 7
A Ausgewählten Jtable Eintrag aus Db löschen Datenbankprogrammierung 9
reibi Derby/JavaDB Derby DB löschen Datenbankprogrammierung 5
P JPA- Entities bleiben nach dem Löschen (unsichtbar?) in der Datenbank Datenbankprogrammierung 6
J Datensätze löschen Datenbankprogrammierung 6
O Löschen vieler Datensätze mit Hibernate Datenbankprogrammierung 11
C Hibernate Datensatz löschen Datenbankprogrammierung 2
U Nur den ersten Datensatz löschen wenn mehrere gleiche da sind Datenbankprogrammierung 2
M Datenbankeintrag bleibt nach Löschen in JSP vorhanden Datenbankprogrammierung 8
D Mit Trigger Tupel löschen verhindern Datenbankprogrammierung 3
L MySQL Einträge löschen schlägt fehl Datenbankprogrammierung 2
F hibernate_seqeunce reseten (löschen) Datenbankprogrammierung 2
J MySQL Löschen von Rows mit JDBC Datenbankprogrammierung 9
M HSQLDB 2.0 - wie tmp-Verzeichnis löschen Datenbankprogrammierung 2
turmaline [Hibernate] @OneToOne: Löschen einer referenzierten Instanz Datenbankprogrammierung 2
G Oracle Zeile löschen Datenbankprogrammierung 2
C SQL String zwei Tabellen vergleichen und gleiche Zeile löschen Datenbankprogrammierung 25
Java.getSkill() Datensatz / Tupel automatisch nach xy Tagen / Stunden löschen Datenbankprogrammierung 7
D SQL : Objekte individuell löschen können Datenbankprogrammierung 5
R JPA, Spring, löschen einer Entity Datenbankprogrammierung 2
H MySQL Einträge löschen Datenbankprogrammierung 5
M Datensatz aus Datenbank löschen Datenbankprogrammierung 6
Antoras Zeile aus DB löschen und ID runterzählen Datenbankprogrammierung 8
C Objekte aus Datenbank löschen Datenbankprogrammierung 6
F Löschen einer Zeile Datenbankprogrammierung 4
G Mit Java-Programm Datenbank löschen/neu anlegen Datenbankprogrammierung 5
G Löschen eines Eintrages verbunden mit JList Datenbankprogrammierung 5
E SQL-Frage (Löschen aller Datensätze) Datenbankprogrammierung 9
P Tabellen löschen Datenbankprogrammierung 4
O Size ResultSet betrachtete Zeilen "löschen" Datenbankprogrammierung 5
G MySQL Zeile löschen und gleich Optimieren Datenbankprogrammierung 6
T [jdbc] einen Eintrag aus mehreren Tabellen löschen (Batch) Datenbankprogrammierung 3
G mySQL: kaskadierendes Löschen Datenbankprogrammierung 7

Ähnliche Java Themen

Neue Themen


Oben