JPA Persistenz vom in GUI veränderten Daten-Modell

looparda

Top Contributor
Ich habe das Problem keinen geeigneten Ansatz zu finden Entities, die in einer JavaFX Applikation modifiziert werden richtig mit JPA abzubilden.
Problem hierbei ist, dass man 4-5 States in der Applikation hat:
1. aktuelle Einträge im View bspw. in einem ListView
2. aktuelle Werte in einem ViewModell
3. aktuelle Werte in einem Modell
(4. State im Persistence Context, falls attached oder detached)
5. Werte in der Datenbank
Für jeden Schichtwechsel benötigt man ein anderes Mapping. Bspw. darf man ein ListView nicht direkt mit der Collection eines Modells binden, falls man ein klassiches Fenstern mit Speichern und Abbrechen benutzt. Andernfalls würden Änderungen ohne, dass der User Speichern möchte ins Modell übertragen, selbst wenn Abbrechen gedrückt wird.
Außerdem müssen Beziehungen in den Collections beider Beziehungs-Enden synchron gehalten werden. Mit einem Binding der Oberfläche und dem Modell würde aber nur die Collection einer Entity die Änderung bekommen. Collections werden durch Hibernate durch eigene Collection-Typen ausgetauscht. Change-Listener auf Hibernate-Collections sind nicht implementiert) Mapping 1-2 erfolgt durch Binding. Für das Mapping 2-3 habe ich mir ein ListCompare überlegt (siehe Code).
Durch das Mapping entsteht viel Overhead und es ist fehleranfällig bei Änderungen.
Das ist nur ein Problem von vielen und ich verstehe nicht wie es so schwer sein kann eine Mini-Anwendung konsistent hinzubekommen. Vielleicht kann jemand open-source Projekte referenzieren, die JavaFX und JPA einsetzen, bei denen man sich etwas abschauen kann. Vielleicht ist meine Architektur auch einfach ungeeignet. Ich würde mich über Erfahrungen und Best Practice Ansätze freuen.

Ich habe aus meinem Projekt, bei dem die Probleme auftraten ein minimales Beispiel extrahiert, da es einfacher ist es zu überschauen und Sachen auszuprobieren:
https://github.com/No3x/javafx-springboot-boilerplate-hibernate-lifecycles-1nn1
 

mrBrown

Super-Moderator
Mitarbeiter
Hast du 'ne ganz kurze Erklärung zu der Domäne? So rein von den Klassen kann ich zumindest aktuell noch nicht den Kontext ableiten, der wäre aber gut, um dazu was zu sagen
Das ist meistens eine sinnvolle Grundlage, um festzulegen, wer für dass aktualisieren einer Beziehung zuständig ist.



Zu dem Problem mit mehren States: ich würde vermutlich hart trennen zwischen dargestellten Daten und Entitys (in sowohl JPA- als auch DDD-Sinne).
Die gesamte Darstellungsschicht würde ich keine Referenzen auf die Entitys halten lassen, und stattdessen mit IDs arbeiten.
Alle anzuzeigenden Daten sind dann als Propertys im ViewModel vorhanden und können dort nach Lust und Laune verändert werden, und erst beim Speichern wird die Entity geladen, die Änderungen vorgenommen und gespeichert. Das Speichern löst dann ein Event aus, nach dem sich alle betroffenen View-Teile die neuen Daten holen.
 

looparda

Top Contributor
Also ich hab das Mini-Projekt ja extrahiert aus meinem eigentlichen Projekt und dachte, es wäre wegen der Anzahl der Entities überschaubar. Es geht in dem Beispiel nur darum Personen und Teams zu verwalten. Personen können mehreren Teams zugeordnet werden, Teams haben mehrere Personen. Da ich in meinem eigentlichen Projekt unbedingt Attribute in der "Auflösungs-Entität" (hier: PersonTeam) benötige habe ich hier die Attribute Datum und einen String "createdBy" dazugenommen. Eine bestimmte Aufgabe hat die gesamte Applikation nicht, außer mein Realsystem möglichst abzubilden von Persistenzschicht bis hoch zur GUI. Viele Probleme treten eben erst mit Verwendung einer GUI au
Alle anzuzeigenden Daten sind dann als Propertys im ViewModel vorhanden
Also würdest du im ViewModel dein Model auseinander nehmen und in Typen wie String, Integer, Date usw. mappen?
Die gesamte Darstellungsschicht würde ich keine Referenzen auf die Entitys halten lassen, und stattdessen mit IDs arbeiten.
Kannst du hier genauer darauf eingehen wie das aussehen würde?
 

mrBrown

Super-Moderator
Mitarbeiter
Also ich hab das Mini-Projekt ja extrahiert aus meinem eigentlichen Projekt und dachte, es wäre wegen der Anzahl der Entities überschaubar.
Technisch schon, aber um irgendwas zu der Struktur zu sagen, ist's meist sinnvoll, von weiter oben darauf zu gucken ;)

Es geht in dem Beispiel nur darum Personen und Teams zu verwalten. Personen können mehreren Teams zugeordnet werden, Teams haben mehrere Personen. Da ich in meinem eigentlichen Projekt unbedingt Attribute in der "Auflösungs-Entität" (hier: PersonTeam) benötige habe ich hier die Attribute Datum und einen String "createdBy" dazugenommen.
Im wesentlichen; es gibt Personen, Teams und Mitgliedschaften?

Ich persönlich würde das mit möglichst nur uni-direktionalen Beziehungen modellieren.
d.h, Personen kennen die Mitgliedschaften nicht direkt (und wenn, nur lesend), genauso Teams, aber Mitgliedschaften kennen Team und Person. Das nimmt meist einen Haufen Probleme bei der Modellierung weg und macht die Nutzung einfacher.

Also würdest du im ViewModel dein Model auseinander nehmen und in Typen wie String, Integer, Date usw. mappen?
Jein, nicht aus die Typen direkt, sonder aus den jeweiligen JavaFX-Propertys.

Kannst du hier genauer darauf eingehen wie das aussehen würde?
Im wesentlichen einfach ein finales Attribut mit dem Typ der ID der jeweiligen Entity, was am besten im Konstruktor direkt zugewiesen wird.
Und dann wie oben gesagt für alle relevanten Felder eine entsprechende Property.

Wenn dann gespeichert wird, wird mit der ID die Entity geladen, die Änderungen (die dann zT einfach die Werte der Properties sind) an der durchgeführt und dann direkt wieder gespeichert.
 

looparda

Top Contributor
Im wesentlichen einfach ein finales Attribut mit dem Typ der ID der jeweiligen Entity, was am besten im Konstruktor direkt zugewiesen wird.
In welchem Konstruktor? - eine neue extra Model-Klasse pro Entity für die GUI?

Wie geh ich mit Collections um? An einer Stelle muss ich dann ja wieder die Unterscheidung machen ob ein Eintrag in die Datenbank eingefügt, bearbeitet oder gelöscht werden soll.
 
Zuletzt bearbeitet:

mrBrown

Super-Moderator
Mitarbeiter
In welchem Konstruktor? - eine neue extra Model-Klasse pro Entity für die GUI?
Das ViewModel eben ;)

Wobei, um bei deinem Beispiel zu blieben: PersonDetailScope würde keine ObjectProperty<Person> mehr haben, sondern eine LongProperty. Die enthält dann statt der Person nur die ID der Person.
(Wobei beide Varianten Vor und Nachteile haben...)
 

looparda

Top Contributor
Das geht vermutlich super bei Entities ohne Collection. Andernfalls läuft es vermutlich darauf hinaus, dass man seine Collection in eine ObservableList<String> mappt. In meinem Beispiel in der GUI habe ich es so, dass sich der rechte ListView in Abhängigkeit des linken ListView aktualisiert. Wenn man eine anderen Person auswählt werden die Teams der Person angezeigt. Dabei gehe ich über das aktuell selektierte Element des linken ListView. Außerdem wird das selektierte Element im PersonDetailScope gespeichert.
Dabei sehe ich das Problem: Du schlägst vor die Id im PersonDetailScope zu speichern und meine Entity in Properties zu mappen. Woher bekomme ich jedoch wieder die id, wenn ich über die GUI nur noch an das aktuell ausgewählte Element der ListView als String komme?
 

mrBrown

Super-Moderator
Mitarbeiter
Das geht vermutlich super bei Entities ohne Collection. Andernfalls läuft es vermutlich darauf hinaus, dass man seine Collection in eine ObservableList<String> mappt.
Oder einfach eine ObservableList<PassendesViewModel> ;)


In meinem Beispiel in der GUI habe ich es so, dass sich der rechte ListView in Abhängigkeit des linken ListView aktualisiert. Wenn man eine anderen Person auswählt werden die Teams der Person angezeigt. Dabei gehe ich über das aktuell selektierte Element des linken ListView. Außerdem wird das selektierte Element im PersonDetailScope gespeichert.
Dabei sehe ich das Problem: Du schlägst vor die Id im PersonDetailScope zu speichern und meine Entity in Properties zu mappen. Woher bekomme ich jedoch wieder die id, wenn ich über die GUI nur noch an das aktuell ausgewählte Element der ListView als String komme?
Naja, du musst ja nicht Strings als Elemente nehmen, du kannst ja immer noch Klassen nehmen, die dann auch die ID enthalten. Ich würde nur Trennen von Objekten für die Darstellung und Entitys.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S ORM-Persistenz & Webservices: Datenabhängigkeit? Allgemeines EE 4
G Persistenz mit Hibernate oder J2EE? Allgemeines EE 11
K Fachkonzept zu Persistenz Mapper Allgemeines EE 2
G Persistenz-Entscheidung (Entity Beans, Hibernate, JDBC) Allgemeines EE 12
S JSP Zwischen zwei Formularen Daten austauschen Allgemeines EE 0
P Daten von HTML and JSP schicken Allgemeines EE 0
D Apache POI Probleme mit Daten(Datum) die aus Formeln entstehen Allgemeines EE 3
C JSF Bestimmte Daten aus der Datenbank anzeigen lassen Allgemeines EE 13
M Daten aus der Resource werden nicht übernommen Allgemeines EE 4
H SQL Daten von Webservice an Client übergeben Allgemeines EE 3
F Servlet Daten im Speicher ablegen Allgemeines EE 3
T Scopes - Daten in JSF-Formular anlegen/bearbeiten, Felder vorbelegen Allgemeines EE 3
A Anfängerfrage: daten in datenbank speichern Allgemeines EE 8
K Daten aus ApplicationServer auf Website darstellen Allgemeines EE 5
C daten von php zu jsp Allgemeines EE 3
MQue Server -> Client zyklische Daten senden Allgemeines EE 20
W Daten mit j2ee aus datenbank abfragen Allgemeines EE 8
M Daten aus JavascriptSeite von Java auswerten lassen Allgemeines EE 3
I Über Formular Daten zu Servlet Allgemeines EE 36
B Session Daten pro User merken Allgemeines EE 9
M EJB Löschen von DB-Daten beim Deployen verhindern Allgemeines EE 2
B JSF - selectOneMenu mit Daten aus faces-config füllen Allgemeines EE 5
J Socket daten darstellen per jsp,servlet Allgemeines EE 2
S Downloadbox auch ohne Daten erzwingen // Content-Disposition Allgemeines EE 6
S Daten in Java schreiben und PHP lesen Allgemeines EE 8
L speichern von daten mittels servlet in xml Allgemeines EE 8
P Tomcat Servlet POST Daten als Array Allgemeines EE 2
S Best-Practice? Daten über Tier-Grenzen hinweg? Allgemeines EE 2
V Bean-Daten in JSF-JSP finden Allgemeines EE 3
D Bekomme DAten von einen Jsp nicht in den Tag Handler Allgemeines EE 2
S JSP - geschichtliche Daten Allgemeines EE 4
F Session Bean -> Daten aus dem Servlet holen Allgemeines EE 11
D Abfrage der header daten funktionieren nicht. Allgemeines EE 2
G Daten aus Inputfeldern in Tabelle speichern Allgemeines EE 6
A JSF - Daten in Session speichern Allgemeines EE 2
S Daten in ein Excel file exportieren Allgemeines EE 3
S Post und Get Daten Allgemeines EE 5
clemson Daten aus Email holen Allgemeines EE 4
J Formular aktualisieren-Daten werden erneut in DB geschrieben Allgemeines EE 6
H daten in session speichern Allgemeines EE 8
A Tabstopp-getrennte Daten üb. Webformular in Datenbank laden! Allgemeines EE 2
T Daten aus der Webseite (JSP) als .txt speichern Allgemeines EE 8
M servlet daten einlesen -> hashmap speichern Allgemeines EE 3
M Speicherung von Daten und JSP Allgemeines EE 9

Ähnliche Java Themen

Neue Themen


Oben