1a0a56a626
Replace the stale multi-module java/mss-failsafe skeleton (old user-management prototype) with the active single-module machine-safety inspection app that was living in its own standalone repo at the repo root. - Remove old java/mss-failsafe/ multi-module tree (mss, userdata, userManagement, mssfailsafe.datalayer, mssfailsafeWeblayer) incl. committed build artifacts - Add the active app (PrimeFaces 11 / JSF 2.3 / Hibernate 5.6 / iText / POI) flattened into java/mss-failsafe/ as the only mss-failsafe in git - Working tree captured = master tip 2a142b5 + in-progress uncommitted work (incl. .github/*.instructions.md AI-context files) - Archive the standalone repo's 33-commit history in GIT_HISTORY_ARCHIVE.md since its .git was not migrated This is the source of truth / base for the upcoming upgraded rewrite.
4.1 KiB
Executable File
4.1 KiB
Executable File
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
- Controller erzeugt neue Entität (id == null).
- Falls Sammlung benötigt: setzt negative ID über createFakeID.
- 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
- Konstruktor setzt creationDate & changedDate.
- Bei Änderungen Fachlogik: changedDate aktualisieren (TODO: zentralisieren via EntityListener).
- 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
@NamedQueryin der Entity definieren.
Performance Hinweise
saveAll(Collection<T>)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)mitentity.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
AbstractEntitynutzen. - Collections initialisieren (z.B.
new ArrayList<>()) im Entity-Konstruktor.