major
#29493
Unnötige Datenbankabfragen bei Löschung von Objekten für historische Referenzen.
Beim Löschen eines Objektes ermittelt die KnowledgeBase (der ReferenceDeletionHelper, bzw. der VETO-Check im DefaultDBContext) alle Referenzen, die auf das gelöschte Objekt zeigen, um diese entsprechend ihrer Löschstrategie (MOReference.DeletionPolicy) anzupassen. Dabei wurden auch Referenzen mit HistoryType.HISTORIC durchsucht.
Das ist überflüssig: Der Wert einer historischen Referenz wird beim Speichern auf eine konkrete Revision stabilisiert (KnowledgeReferenceStorageImpl.storeHistoryContext()), die Revisionsspalte enthält daher nie Revision.CURRENT_REV. Gelöscht werden können ausschließlich aktuelle Objekte. Eine historische Referenz kann also nie auf ein gelöschtes Objekt zeigen, und ihre Löschstrategie kann nie greifen.
Da die Standard-Löschstrategie CLEAR_REFERENCE ist (MOReference.DEFAULT_DELETION_POLICY), betraf das jede historische Referenz einer Anwendung, an der keine Löschstrategie explizit gesetzt ist. Bei jeder Löschung wurde daher für jede solche Referenz eine Datenbankabfrage abgesetzt, die garantiert kein Ergebnis liefern kann.
Umsetzung
DBKnowledgeBase.anyRefereesQuery() bekommt den zusätzlichen Parameter currentTargets. Ist er gesetzt, überspringt die Query-Erzeugung (Expressions.createMonomorphicQueriesForTypeAndAttribute()) historische Referenzen vollständig, so dass für sie weder eine Query erzeugt noch abgesetzt wird. Der Parameter geht in den Query-Cache-Schlüssel ein.
Die Suche über alle Referenzen unabhängig von der Löschstrategie (getAnyReferer() mit policy == null) findet historische Referenzen unverändert; dort wird der Parameter aus dem Zielobjekt abgeleitet.
Referenzen mit HistoryType.MIXED werden weiterhin durchsucht, da sie auf aktuelle Objekte zeigen können.
Test
- com.top_logic/src/test/java/test/com/top_logic/knowledge/service/db2/reference/historic/global/TestDeletion.java