diff --git a/README.md b/README.md index 3d91391c3b6dc5d424a124c5228e54dd58a921b3..0df3f29e61cc0de43d15da7b4252dd9e9c428c12 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ + # NoSQL-Datenbank für My-Aktion ## Worum geht es in diesem Projekt? -Die Aufgabe dieses Projekts ist es die relationale H2-Datenbank des Projekts my-aktion durch die NoSQL-Datenbank MongoDB zu ersetzen, sowie dem anpassen von my-aktion an die neue Datenbank. - -Zur Umsetzung wurde das Mapping-Framework Hibernate OGM genutzt. Hibernate OGM mappt die Entities der Anwendung nicht wie Hibernate ORM, an eine relationale Datenbank sondern an eine NoSQL-Datenbank. Im Falle des Projekt also an die MongoDB-Datenbank. -Hibernate OGM ist dazu in der Lage JPQL-Queries zu übersetzen in die Sprache der jeweilig angebundenen Datenbank. Der Programmierer muss also die Abfragesprache der genutzten Datenbank nicht zwangsläufig kennen. Auch die von der Anwendung genutzten JPA-Annotationen wie zum Beispiel *NotNull* oder *ManyToOne* werden unterstützt, also müssen auch hier keine Anpassungen vorgenommen werden. +Die Aufgabe dieses Projekts ist es die relationale H2-Datenbank des Projekts my-aktion durch die NoSQL-Datenbank MongoDB zu ersetzen, sowie dem Anpassen von my-aktion an die neue Datenbank. + +Zur Umsetzung wurde das Mapping-Framework Hibernate OGM genutzt. Hibernate OGM mappt die Entitäten der Anwendung nicht wie Hibernate ORM, an eine relationale Datenbank, sondern an eine NoSQL-Datenbank. Im Falle des Projekts also an die MongoDB-Datenbank. + +Hibernate OGM ist dazu in der Lage JPQL-Queries zu übersetzen in die Sprache der jeweils angebundenen Datenbank. Der Programmierer muss also die Abfragesprache der genutzten Datenbank nicht zwangsläufig kennen. Auch die von der Anwendung genutzten JPA Annotationen wie zum Beispiel *NotNull* oder *ManyToOne* werden unterstützt, also müssen auch hier keine Anpassungen vorgenommen werden. ## Aufgetretene Probleme ### Aggregatfunktionen in Hibernate OGM -Da Hibernate OGM ein laufender Prozess ist können bislang nur manche Sprachkonstrukte von JPQL in andere Abfragesprachen übersetzt werden. Was genau übersetzt wird unterscheidet sich je nach genutzter Datenbank. Die Version für MongoDB-Datenbanken unterstützt die folgenden Konstrukte von JPQL: +Da Hibernate OGM ein laufender Prozess ist können bislang nur manche Sprachkonstrukte von JPQL in andere Abfragesprachen übersetzt worden. Was genau übersetzt wird, unterscheidet sich je nach genutzter Datenbank. Die Version für MongoDB-Datenbanken unterstützt die folgenden Konstrukte von JPQL: - einfache Vergleiche mit "<", "<=", "=", ">=" und ">" - `IS NULL` und `IS NOT NULL` @@ -18,9 +20,9 @@ Da Hibernate OGM ein laufender Prozess ist können bislang nur manche Sprachkons - `LIKE`, `IN` und `BETWEEN` - `ORDER BY` -Im Projekt my-aktion wird an einer Stelle die SQL-Aggregatfunktion SUM genutzt, in der Dokumentation werden diese nicht bei unterstützten Konstrukten aufgezählt. Allerdings scheint denoch zumindest eine teilweiße Unterstützung für HQL zu bestehen. Näheres weiter unten. Die restlichen Queries konnten Problemlos weiter genutzt werden ohne spezielle Anpassungen vornehmen zu müssen. - -Der unten dargestellte Code zeigt die Methode in welcher die Abfrage mit der Summenfunktion aufgerufen wird. Der einzige Unterschied zwischen diesem und den anderen Methoden in der Klasse ist der dass anstatt der JPA-API die Hibernate-Native-API genutzt wird und damit HQL anstatt JPQL. +Im Projekt my-aktion wird an einer Stelle die SQL-Aggregatfunktion SUM genutzt, in der Dokumentation werden diese nicht bei unterstützten Konstrukten aufgezählt. Allerdings scheint dennoch zumindest eine teilweise Unterstützung für HQL zu bestehen. Näheres weiter unten. Die restlichen Abfragen konnten problemlos weiter genutzt werden ohne spezielle Anpassungen vornehmen zu müssen. + +Der unten dargestellte Code zeigt die Methode, in welcher die Abfrage mit der Summenfunktion aufgerufen wird. Der einzige Unterschied zwischen diesem und den anderen Methoden in der Klasse ist der, dass anstatt der JPA-API die Hibernate-Native-API genutzt wird und damit HQL anstatt JPQL. @RolesAllowed("Organizer") @Stateless @@ -46,27 +48,28 @@ Der unten dargestellte Code zeigt die Methode in welcher die Abfrage mit der Sum } -Da im Code nur auf das Session-Interface zugegriffen wird und nicht direkt auf die OgmSession, sollte die Methode auch mit einer Hibernate-ORM-Lösung lauffähig sein, müsste also nicht extra angepasst werden. Der Nachteil dieser Methode ist allerdings dass die reine Nutzung von JPA damit entfällt und somit nicht einfach auf eine andere Implementierung wie zum Beispiel EclipseLink umgestiegen werden könnte. - -Die Lösung wurde auf der folgenden Webseite gefunden https://www.gregoriopalama.com/mongodb-on-wildfly-using-hibernate-ogm/ - -Nach weiterer Recherche warum das genannte funktioniert, obwohl gegenteiliges in der Dokumentation behauptet wird, konnten folgende JIRA-Einträge von Hibernate OGM gefunden werden. - -- https://hibernate.atlassian.net/browse/OGM-534 -- https://in.relation.to/2018/12/18/hibernate-ogm-5-4-1-Final-released/ -- https://hibernate.atlassian.net/browse/OGM-1530 - -Beide sind als erledigt markiert. Im ersten wird Support für die SQL-Aggregatfunktion Count hinzugefügt. Diese Änderung ist bereits veröffentlicht worden in der Version 5.4.1 (siehe zweiter Link) welche die aktuelle Veröffentlichung darstellt und die im Projekt genutzte. - -Des Weiteren ist auf der ersten Seite die Aufgabe verlinkt die weiteren Aggregatfunktionen zu implementieren. Die verlinkte Aufgabe ist der dritte Link. Wenn man sich den Github Link für den dazugehörigen Pull Request ansieht und dessen Kommentare und Commits sieht es so aus als ob die Änderungen bereits veröffentlicht wurden die Dokumentation diesbezüglich aber nicht aktualisiert worden ist. - -Eine mögliche Alternative wäre es den NamedQuery mit der *criteria-only find syntax* oder der *MongoDB CLI syntax* und einem NativeNamedQuery zu schreiben. Da ein einfaches wechseln zwischen Hibernate ORM und OGM dadurch erschwert werden würden wurde bewusst darauf verzichtet. +Da im Code nur auf das Session-Interface zugegriffen wird und nicht direkt auf die OgmSession, sollte die Methode auch mit einer Hibernate-ORM-Lösung lauffähig sein, müsste also nicht extra angepasst werden. Der Nachteil dieser Methode ist allerdings dass die reine Nutzung von JPA damit entfällt und somit nicht einfach auf eine andere Implementierung wie zum Beispiel EclipseLink umgestiegen werden könnte. + +Die Lösung wurde auf der folgenden Webseite gefunden https://www.gregoriopalama.com/mongodb-on-wildfly-using-hibernate-ogm/ + +Nach weiterer Recherche warum das genannte funktioniert, obwohl gegenteiliges in der Dokumentation behauptet wird, konnten folgende JIRA-Einträge von Hibernate OGM gefunden werden. + +- https://hibernate.atlassian.net/browse/OGM-534 +- https://in.relation.to/2018/12/18/hibernate-ogm-5-4-1-Final-released/ +- https://hibernate.atlassian.net/browse/OGM-1530 + +Beide sind als erledigt markiert. Im ersten wird Support für die SQL-Aggregatfunktion Count hinzugefügt. Diese Änderung ist bereits veröffentlicht worden in der Version 5.4.1 (siehe zweiter Link) welche die aktuelle Veröffentlichung darstellt und die im Projekt genutzte. + +Des Weiteren ist auf der ersten Seite die Aufgabe verlinkt die weiteren Aggregatfunktionen zu implementieren. Die verlinkte Aufgabe ist der dritte Link. Wenn man sich den Github Link für den dazugehörigen Pull Request ansieht und dessen Kommentare und Commits sieht es so aus als ob die Änderungen bereits veröffentlicht wurden die Dokumentation diesbezüglich aber nicht aktualisiert worden ist. + +Eine mögliche Alternative wäre es den NamedQuery mit der *criteria-only find syntax* oder der *MongoDB CLI syntax* und einem NativeNamedQuery zu schreiben. Da ein einfaches Wechseln zwischen Hibernate ORM und OGM dadurch erschwert werden würden wurde bewusst darauf verzichtet. + - MongoDB Native Queries: https://docs.jboss.org/hibernate/stable/ogm/reference/en-US/html_single/#ogm-mongodb-queries-native ### Organizer-Dokument -Da die Dokumente in einer MongoDB-Datenbank immer einen eindeutigen Identifier im Feld *_id* haben müssen, wurde in die Organizer-Entity ein Feld Id eingefügt welches das email-Feld als Identifier ersetzt. Damit dennoch sichergestellt wird das eine bestimmte E-Mail nur einmal vorkommt in der Tabelle, wurde an das email-Feld die Annotation @Column(unique = true) angehängt (siehe untenstehender Code). +Da die Dokumente in einer MongoDB-Datenbank immer einen eindeutigen Identifier im Feld *_id* haben müssen, wurde in die Organizer-Entität ein Feld id eingefügt welches das email-Feld als Identifier ersetzt. Damit dennoch sichergestellt wird das eine bestimmte E-Mail nur einmal vorkommt in der Tabelle, wurde an das email-Feld die Annotation @Column(unique = true) angehängt (siehe untenstehender Code). @Entity public class Organizer extends DateEntity { @@ -102,10 +105,10 @@ Da die Dokumente in einer MongoDB-Datenbank immer einen eindeutigen Identifier i ## Wie startet man das Projekt? ### Voraussetzungen -- Eine MongoDB-Datenbank-Instanz muss auf dem Rechner laufen (unter default port und localhost). -- Die Datenbank muss den Namen my-aktion haben. -- Es muss eine Sammlung namens Organizer existieren in welchen die Benutzer der Applikation gespeichert werden. -- Die in der Anwendung der Vorlesung erstellten Benutzer Martha und Max Mustermann sind in der organizers.json Datei enthalten (Diese befindet sich im Ordner etc des Projekts) und können in die Organizer-Sammlung importiert werden. Hier ist zu beachten dass das Feld _id als ein Int64-Datentyp erstellt wird und nicht als ein Int32-Datentyp. Die Standard-Einstellung ist der Int32-Datentyp. Der Int64-Datentyp entspricht einem Long in Java, da die Entity ebenfalls ein Long wird ansonsten eine Exception geworfen. +- Eine MongoDB-Datenbank-Instanz muss auf dem Rechner laufen (unter dem Standard Port und localhost). +- Die Datenbank muss den Namen *my-aktion* haben. +- Es muss eine Sammlung namens Organizer existieren in welchen die Benutzer der Applikation gespeichert werden. +- Die in der Anwendung der Vorlesung erstellten Benutzer Martha und Max Mustermann sind in der organizers.json Datei enthalten (Diese befindet sich im Ordner etc des Projekts) und können in die Organizer-Sammlung importiert werden. Hier ist zu beachten dass das Feld _id als ein Int64-Datentyp erstellt wird und nicht als ein Int32-Datentyp. Die Standard-Einstellung ist der Int32-Datentyp. Der Int64-Datentyp entspricht einem Long in Java, da die Entität ebenfalls ein Long enthält wird bei dem Int32-Datentyp eine Exception geworfen. - Das Projekt MongoDB Login Modul muss fertig konfiguriert sein (siehe https://gitlab.reutlingen-university.de/hornerj/mongo-db-login-module). ### Ausführen @@ -115,5 +118,6 @@ Das Projekt kann auf herkömmlich genutzte Weiße deployt werden also zum Beispi oder auch über die Benutzerschnittstelle von Wildfly die HAL-Management-Konsole. -Ansonsten sind keine besonderen Schritte zu tätigen. + +Ansonsten sind keine besonderen Schritte zu tätigen.