# Manager/Controller Pattern Instructions Aktualisiert: 2025-10-20 ## Ziele Klare Trennung zwischen UI-Zustand (Controller) und Geschäftslogik/Persistenz (Manager). ## Verantwortlichkeiten Controller: - Zustände: selected, created, entities. - UI Nachrichten (FacesMessage). - Dialogsteuerung (PrimeFaces Widgets schließen). - Hilfsfunktionen (PDF, Fake-ID-Erzeugung). Manager: - CRUD Operationen (create, edit, save, saveAll, remove, removeAllIn, find, findAll). - Fachspezifische Queries / Reload. - Fehlerlogging. ## Interaktion - Controller ruft Manager.save / saveAll auf für Persistenz. - Nach Änderungen: Controller.refrehSelected() (Tippfehler) -> aktualisiert ausgewähltes Objekt. - Kein direkter EntityManager Zugriff im Controller. ## Fake-ID Ablauf 1. Controller erzeugt neue Entität (id == null). 2. Falls Sammlung benötigt: setzt negative ID über createFakeID. 3. Bei Save: Manager erkennt id < 0 (nach vorherigem Nullsetzen) -> persist. ## Methoden-Namenskonventionen - Manager: Verb + Domänenobjekt (addQuestionnaireToSecurityArea, removeQuestionnaireFromSecurityArea). - Controller: UI Aktionen (saveSelected, createNew, openDialog, closeDialogs). ## Edge Cases - selected == null bei refresh -> no-op. - entities Liste leer -> UI Tabelle zeigt keine Einträge; Null vermeiden (immer leere Liste). ## Messaging - Erfolg: `successMessage()`; Fehler: `errorMessage()`. - Spezifische Warnungen über `sendWarnMessage`. ## Verbesserungen - Umbenennung `refrehSelected()` -> `refreshSelected()` in Basisklasse + alle Verwendungen. - Einführung eines BasePDFController oder Utility zur Auslagerung PDF Logik. ## Generator Leitplanken - Zusätzliche Logik (berechnete Felder, Validierungen) zuerst im Manager statt im Controller (besser testbar, wiederverwendbar). - Controller schlank halten: keine komplexe Businessregeln. --- # Persistence Instructions Aktualisiert: 2025-10-20 ## Ziele Konsistente JPA Nutzung (Java EE 8, Hibernate Provider) mit klaren Regeln für IDs, Lazy Loading und Flush. ## Grundsätze - Entities extend `AbstractEntity` (Long id, creationDate, changedDate, outdated Flag). - Identity Generation: `@GeneratedValue(strategy = GenerationType.IDENTITY)` -> Kein manuelles Setzen positiver IDs. - Equals/HashCode nur auf ID (Basis-Klasse bereitgestellt). ## ID & Fake-ID Handling - Temporäre neue Objekte können negative IDs erhalten (Fake) zur UI-Differenzierung. - Vor persist: if id != null && id < 0 -> `setId(null)` damit JPA eine echte ID generiert. - Niemals persist mit negativer ID ausführen. ## Lebenszyklus 1. Konstruktor setzt creationDate & changedDate. 2. Bei Änderungen Fachlogik: changedDate aktualisieren (TODO: zentralisieren via EntityListener). 3. Persist -> flush direkt in `AbstractManager.save` / `saveAll`. ## Lazy Loading - Vermeide direkte Iteration über nicht initialisierte Collections außerhalb Transaktion. - Nutzung `AbstractManager.refresh(entity)` initialisiert das Entity (Hibernate.initialize(entity)). - Für Collections eigene Reload-Methoden in spezialisierten Managern implementieren. ## Named Queries & Criteria - Bevorzugt Criteria API für dynamische Filter. - Häufig verwendete, statische Abfragen als `@NamedQuery` in der Entity definieren. ## Performance Hinweise - `saveAll(Collection)` nutzt einen Flush am Ende; reduziert DB Roundtrips. - Bulk Delete oder Update lieber über JPQL statt Einzelloops (aktuell: removeAllIn loop; Optimierungspotential). ## Edge Cases - `save(null)` => false (kein Fehlerwurf, Logging im Manager). - Leere Collections in `saveAll` => true (no-op). - `remove(entity)` mit `entity.getId()==null` => false; vorher persistieren oder ignorieren. ## Verbesserungs-Ideen - EntityListener für Timestamps. - Soft Delete (outdated Flag) statt physischem Löschen für Audit. - Einführung eines Version-Feldes für Optimistic Locking. ## Generator Leitplanken - Keine Änderung der ID-Strategie ohne umfassende Migration. - Bei neuen Entities standardisierte Felder aus `AbstractEntity` nutzen. - Collections initialisieren (z.B. `new ArrayList<>()`) im Entity-Konstruktor. ---