Ich versuche, die Annotation @SQLDelete
von Hibernate zu verwenden, um das Löschen zu vereinfachen. Es funktioniert gut, wenn das DB-Schema statisch ist, d. H. Es in SQL übergeben.
Leider scheint die SQL-Anweisung unverändert an EntityPersister
s übergeben zu werden (vgl.% Co_de% s Methode EntityClass
, so dass ich keine Möglichkeit finde, den Schemanamen dynamisch zu übergeben, wie in Native-SQL-Abfragen mit CustomSQL createCustomSQL(AnnotationInstance customSqlAnnotation)
< br>
Hat jemand eine gute Abhilfe für dieses Problem gefunden (ich verwende Hibernate 4.3.5)?
Bearbeiten: Wenn es keine echte Lösung gibt, habe ich am Ende die Codequelle von {h-schema}
geändert, indem ich beim Platzieren der benutzerdefinierten SQL-Abfragen in der Methode org.hibernate.persister.entity.AbstractEntityPersister
den Schema-Platzhalter ersetzt habe.
Bearbeiten2 : Ich habe ein Problem für dieses Verhalten in Hibernate JIRA erstellt. Ich werde später einen Pull Request erstellen und ich wünsche, dass das Hibernate Team es akzeptiert.
Als verknüpfter Autor unten angegeben:
Ich arbeite gerade an einer Seam-Anwendung, die eine sanfte Löschung in der Datenbank benötigt. Auf der rechten Seite können Sie einen Ausschnitt meines Datenbankdiagramms sehen, das eine Tabelle CUSTOMER
und APP_USER
enthält. Dies ist nur eine direkte Eins-zu-viele-Beziehung, aber das Wichtigste, was zu beachten ist, ist das Feld "DELETED" in jeder Tabelle. Dies ist das Feld, das verwendet wird, um das Löschen zu verfolgen. Wenn das Feld eine '1' enthält, wurde der Datensatz gelöscht, und wenn er eine '0' enthält, wurde der Datensatz nicht gelöscht.
Vor ORMs wie Hibernate hätte ich diese Flagge selbst mit SQL verfolgen und setzen müssen. Es wäre nicht sehr schwer zu tun, aber wer möchte eine Reihe von Standard-Code schreiben, nur um zu verfolgen, ob ein Datensatz gelöscht wurde oder nicht. Dies ist, wo Hibernate und Anmerkungen zur Rettung kommt.
Im Folgenden sind die 2 Entity-Klassen aufgeführt, die von Hibernate mithilfe von seamgen generiert wurden. Ich habe Teile des Codes aus Gründen der Übersichtlichkeit weggelassen.
Die folgenden 2 Schritte waren alles, was ich tun musste, um das Löschen zu implementieren.
@SQLDelete
wurde hinzugefügt, die den Standard überschreibt
Hibernate-Löschung für diese Entität. @Where
wurde hinzugefügt, um die Abfragen zu filtern und nur zurückzukehren
Datensätze, die nicht gelöscht wurden. Beachten Sie auch, dass in der
CUSTOMER class Ich habe der AppUsers-Sammlung @Where
hinzugefügt. Das ist
benötigt, um nur die appUsers für diesen Kunden zu holen, die nicht haben
wurde weich gelöscht. Viola! Wenn Sie nun diese Entitäten löschen, wird das Feld "DELETED" auf "1" gesetzt, und wenn Sie diese Entitäten abfragen, werden nur Datensätze zurückgegeben, die eine '0' im "DELETED" enthalten. Feld.
Kaum zu glauben, aber das ist alles, was Soft Loeses mit Hibernate-Annotationen implementiert.
Beachten Sie auch, dass Sie anstelle der @Where(clause="deleted ‘1’")
-Anweisungen den Hibernate-Filter verwenden können ( Ссылка ), um alle 'gelöschten' Entitäten global herauszufiltern. Ich fand, dass die Definition von 2 Entity-Managern ("normale", die gelöschte Elemente filtern, und eines, das dies nicht tut, für die seltenen Fälle ...) normalerweise ziemlich bequem ist.
Sie können ein DeleteEventListener
wie:
hake es in deine persistence.xml wie folgt ein
%Vor%Vergessen Sie auch nicht, Ihre Kaskaden in Ihren Anmerkungen zu aktualisieren.