Aufgabensammlung zu Java Data Objects JDO Lösungen Dr. Arno Schmidhauser Letzte Revision: November 2004 Email: [email protected] Webseite: http://www.sws.bfh.ch/db Aufgabensammlung zu Java Data Objects JDO 2 Inhalt 1 2 3 4 JDO Allgemein ........................................................................... Programmieren von JDO-Applikationen ......................................... Transaktionsmodell .................................................................... OR-Mapping .............................................................................. November 2004 Arno Schmidhauser 3 4 5 7 SWS Aufgabensammlung zu Java Data Objects JDO 1 JDO Allgemein 1. Identifizieren Sie aus ihrer Sicht die wesentlichen Merkmale und Vorteile der JDO-Technologie. 3 Keine Musterlösung 2. Welcher konzeptionelle Unterschied besteht zwischen den Methoden PersistenceManager.makePersistent( o ) und PersistenceManager.deletePersistent( o ). Im ersten Fall werden alle Objekte, die von o aus erreichbar sind, ebenfalls persistent. Im zweiten Fall wird einzig das Objekt o gelöscht. 3. 4. Nennen Sie Beispiele für die Anwendung der Instance Callbacks. Verschlüsselung Kompression Sicherstellung von referentiellen oder semantischen Integritätsbedingungen. Benachrichtigung anderer Transaktionen oder Applikationen über geänderte Objekte (Event-Mechanismus). Welcher Unterschied besteht zwischen First Class Objects und Second Class Objects (Verwenden Sie die JDO-Spezifikation Kapitel 6.3 und 18.4)? Haben Second Class Objects auch Vorteile? Second Class Objects (SCOs) sind eingebettet in First Class Objects (FCOs) und haben keine eigene Identität. Der Grundmechanismus für den Transport ist Serialisierung. Second Class Objekte dürfen auf keinen Fall von verschiedenen First Class Objects aus verwendet werden. Im Rahmen des Konfigurationsfiles werden SCOs als embedded gekennzeichnet. Insbesondere bei Collections kann oft gewählt werden, ob sie als FCOs oder SCOs (embedded) in der Datenbank abgelegt werden sollen. SCOs können nicht abgefragt werden im Rahmen von JDOQL. SCOs gehören zu keinem Extent ihrer Klasse. Mögliche Vorteile von SCOs: Grössere Kollektionen von kleinen Objekten sind effizienter verwaltbar (Platz, Zuweisung einer ID, automatisches Löschen mit FCO zusammen). Per Default sind alle primitiven Typen und ihre Wrapper-Klassen, sowie Date, Locale und einige Set- und Map-Klassen SCOs. Auch Arrays von obigen Klassen sind per Default SCOs. 5. Welche Java Datentypen und Klassen müssen per default persistent sein gemäss JDO Spezifikation? Siehe Kapitel 18.4, Abschnitt 'default persistence modifier' November 2004 Arno Schmidhauser SWS Aufgabensammlung zu Java Data Objects JDO 6. 4 Wozu dienen die XML-Elemente collection, map und array im JDO Konfigurationsfile? (Siehe Kapitel 18.4) Festlegung des Datentyps der Collection-Elemente in Collections. Bei Maps muss der Datentyp (Klasse) der Key- und der Value-Elemente festgelegt werden. Bei Arrays ist der Typ der Elemente gegeben. Festlegung, ob die Collection-, Map- oder Array-Elemente eingebettet oder nicht eingebettet sind. 2 Programmieren von JDO-Applikationen Auf der Datenbank-Homepage finden Sie unter 'ProgrammierWorkshops' -> 'JDO-Workshop' Vorlagen zum Anwendungsbeispiel der Persistent Message Queue. Installationspakete für bestimmte Produkte finden Sie unter 'Downloads' -> 'Produkte'. Die Aufgaben 7 bis 11 können Sie mit Hilfe der Objekt-Datenbank ObjectDB am bequemsten lösen. Eine Anleitung finden Sie unter jdo-workshop/PMQApplication-ObjectDB/Vorlagen/README.txt. 7. Vervollständigen Sie die Java-Klasse PMQInit.java, welche eine persistente Message Queue erzeugt. Diese Klasse entspricht sinngemäss einem SQL-Initialisierungskript für relationale Datenbanken. Siehe Java-Code zu den Lösungen in jdo-workshop.zip 8. Vervollständigen Sie die Java-Klassen FatMessageProducer.java und FatMessageConsumer.java zu lauffähigen Klassen. Gehen Sie von folgender Zusatzbedingung aus: Message-Objekte sollen vom Consumer in der Datenbank nicht gelöscht, sondern nur aus der PMQ entfernt werden. Im Consumer also die Methode PersistenceManager.deletePersistent() nicht verwenden. Siehe Java-Code zu den Lösungen in jdo-workshop.zip 9. Vervollständigen Sie die Klasse FatMessageSelector.java. Diese soll alle Meldungen einer Message Queue mit einer bestimmten Priorität ausgeben. Als Suchbedingungen sollen der Name und die Priorität der gesuchten Meldungen angegeben werden können. Erweitern Sie das Programm so, dass auch die Objekt ID der PMQ ausgegeben wird. Die Objekt ID soll auch als Suchbedingung für die PMQ angegeben werden können. Siehe Java-Code zu den Lösungen in jdo-workshop.zip 10. Erstellen Sie eine Klasse GarbageCollector.java. Diese Klasse kann periodisch aufgerufen werden, um nicht mehr benötigte Message-Objekte aus der Datenbank physisch zu löschen. November 2004 Arno Schmidhauser SWS Aufgabensammlung zu Java Data Objects JDO 5 Siehe Java-Code zu den Lösungen in jdo-workshop.zip 11. Stellen Sie den Code von MTSTMessageProducer fertig und zeigen sie auf, wie gross der Performance-Gewinn einer multi-threadedLösung mit periodischem Commit gegenüber einer single-threadedLösung mit Commit pro Message ist. Der Performance-Gewinn kann sich zwischen einem Faktor 1 und 100 bewegen bei der Multithreaded-Lösung. Natürlich muss in Kauf genommen werden, dass innerhalb des Commit-Intervalles alle Meldungen verlorengehen können. Siehe auch Java-Code zu den Lösungen in jdo-workshop.zip 12. Erstellen Sie mit Hilfe der Kodo-Workbench ein Mapping der Persistent Message Queue auf eine relationale Datenbank. Eine Anleitung finden Sie unter jdo-workshop/PMQApplication-KODOHypersonic/Vorlagen/README.txt. Entscheiden Sie sich wahlweise a) für ein vertikales Tabellenmapping mit möglichst hoher Auflösung aller Java-Klassen und -Member auf relationale Tabellen oder b) für ein flaches Tabellenmapping mit möglichst hoher Einbettung aller Messages in die PMQ-Tabelle. Siehe Java-Code zu den Lösungen in jdo-workshop.zip 3 Transaktionsmodell 13. Gegeben sei folgendes Programm-Fragment aus einem MessageConsumer: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) Transaction tra = pm.currentTransaction(); tra.begin(); PMQ pmq = (PMQ) pm.getObjectById( "2230", true ); tra.commit(); // ... tra.begin(); Message m = pmq.get(); pmq.remove( m ); System.out.println( m.toString() ); tra.commit(); Ausserdem ist noch folgende Information aus der JDO-Spezifikation gegeben: JDO instances that represent specific persistent data in the data store, but whose values are not in the JDO instance, are hollow. The hollow state provides for the guarantee of uniqueness for persistent instances between transactions. This is permitted to be the state of instances committed from a previous transaction, acquired by the method getObjectById, returned by iterating an Extent, returned in the result of a query execution, or navigating a persistent field reference. However, the JDO implementation may choose to return instances in a different state reachable from hollow. November 2004 Arno Schmidhauser SWS Aufgabensammlung zu Java Data Objects JDO 6 Welche Zustände durchläuft das Objekt pmq im Verlauf dieses Programmes? Kann in Zeile 7 garantiert auf das pmq Objekt zugegriffen werden? Zustände des Objektes pmq Nach Nach Nach Nach 3 bis und mit 6: 7: 8: 10: Hollow P-clean P-dirty Hollow In 7 kann auf das Objekt pmq zugegriffen werden. Die ID bleibt ja auch im Zustand Hollow erhalten. Falls eine andere Transaktion das Objekt im Verlauf von 5 löscht, was prinzipiell möglich ist, wird bei 7 eine Fehlermeldung ausgegeben. 14. Eine portable JDO-Applikation darf gemäss Standard gegenüber ihrer Datenbank nur vom Isolationsgrad READ COMMITTED ausgehen. Das heisst, vor dem Lesen eines Objektes wird darauf eine Lesesperre gesetzt. Diese Lesesperre wird unmittelbar nach dem Lesevorgang zurückgegeben (Beim Isolationsgrad REPEATABLE READ würde sie bis zum commit-Befehl beibehalten) . Ist unter diesen Voraussetzungen im Ablauf bei Aufgabe 13 die Queue Semantik (Jede Meldung wird nur einmal gelesen) garantiert, auch wenn mehrere Consumer-Prozesse (das heisst mehrere Java Virtual Machines mit einer JDO-Applikation) gleichzeitig laufen? Unter JDO-Spezifikationen (READ COMMITTED) ist die Queue-Semantik nicht garantiert. Zwei Prozesse können eine Message gleichzeitig lesen. Das Löschen der Message wird vom ersten Prozess korrekt durchgeführt, das Löschen der Message durch den zweiten Prozess geht ins Leere. Abhilfe im Rahmen des JDO-Standards: Optimistische Transaktionen verwenden, und die Ausgabe/Weitergabe einer Message in der Applikation erst durchführen, wenn das Austragen aus der Queue und der commit-Befehl erfolgreich waren. Spezifische Abhilfe mit Relationalen Datenbanken: Der benötigte Isolationsgrad REPEATABLE READ kann über JDBC-Optionen meist eingestellt werden. OO-Datenbank Versant: Bei 7 wird eine Lesesperre auf pmq gesetzt, bei 8 wird eine Schreibsperre gesetzt. Es könne also nicht zwei Prozesse gleichzeitig die Meldung aus der Queue austragen. Jedoch kann bei 8 ein Deadlock auftreten, die Datenbank setzt für einen der zugreifenden Prozesse die Löschung der Meldung zurück. Damit wird aber 9 übersprungen und in eine Exceptionbehandlung verzweigt. Die Meldung wird also im zurückgesetzten Prozess nicht gelesen. OO-Datenbank ObjectDB: Es muss mit Optimistischer Transaktionskontrolle gearbeitet werden, da Sperren (auch Schreibsperren!) erst zum Commit-Zeitpunkt gesetzt werden (Siehe entsprechendes Memo). 15. Gegeben sei folgendes Programm-Fragment aus einem MessageConsumer, ohne Verwendung einer Transaktion: November 2004 Arno Schmidhauser SWS Aufgabensammlung zu Java Data Objects JDO (1) (2) (3) (4) (5) 7 PMQ pmq = (PMQ) pm.getObjectById( "2230", true ); Message m = pmq.get(); System.out.println( m.toString() ); pmq.remove( m ); // Ende des Programmes Ausserdem seien folgende Properties gesetzt: javax.jdo.option.NonTransactionalRead = true. javax.jdo.option.NonTransactionalWrite = true. Welche Zustände durchläuft das Objekt pmq im Verlauf dieses Programmes? Zustände des Objektes pmq Nach 1: Nach 2: Nach 4: Hollow P-Nontrans P-Nontrans Es findet kein Abgleich des modifizierten Objekte in der Datenbank statt. Die Änderung geht verloren. Der folgende Code würde nichts nützen, da bei Schritt 6, der aktuelle Zustand aus der Datenbank gelesen wird, und die Änderungen im Zustand P-Nontrans aus Schritt 4 verloren geht. (1) (2) (3) (4) (5) (6) (7) (8) 16. PMQ pmq = (PMQ) pm.getObjectById( "2230", true ); Message m = pmq.get(); System.out.println( m.toString() ); pmq.remove( m ); tra.begin(); pm.makeTransactional( pmq ); tra.commit(); // Ende des Programmes Starten Sie gleichzeitig mehrere Producer und Consumer-Prozesse mit ihrem JDO-Produkt. Entspricht das Verhalten vollständig der Queue-Semantik oder ergeben sich Probleme? Wenn Probleme auftreten, versuchen Sie sie zu beheben. Siehe Java-Code zu den Lösungen in jdo-workshop.zip. Beachten Sie auch das Technologie Memo über Locking und Indexing in ObjectDB. 4 OR-Mapping Grundlage für die Fragen in diesem Kapitel ist das TechnologieMemo KodoJDO-Relational-Mapping.pdf. 17. Wie äusserst sich die Angabe embedded="true" oder embeddedelements="true" für Collection-Objekte in den Tabellen einer relationalen Datenbank? Die beiden Angaben sind unabhängig voneinander. Mit der Angabe embedded="true" wird die Collection an sich (beispielsweise das Vector- oder November 2004 Arno Schmidhauser SWS Aufgabensammlung zu Java Data Objects JDO 8 das ArrayList-Objekt) in ein Tabellenattribut serialisert. Mit der Angabe embeddedelments="true" werden die Objekte auf welche das Collection-Objekt zeigt, serialisiert. Sind beide Angabe auf true gesetzt, entsteht aus der Collection und ihren referenzierten Objekten ein einziges serialisiertes Attribut. 18. Welche Bedeutung hat das Attribut JDOCLASS in den DatenbankTabellen? Es definiert die Java-Klasse, von der Instanzen erzeugt werden müssen, welche die Werte der übrigen Attribute des Datensatzes enthalten. 19. Welche Bedeutung hat das Attribut JDOVERSION in den DatenbankTabellen? Es repräsentiert den aktuellen Objektzustand. Mit Hilfe dieses Attributes wird das Optimistische Concurrency-Control realisert. Es ist an sich ein Zeitstempel der letzten Veränderung an diesem Datensatz. 20. Welche Bedeutung hat das Attribut MESSAGES_ORDER in der Datenbank-Tabelle PMQ_MESSAGES? Es definiert die Position eines Listen-Element bei Collection-Objekten vom Typ List. In relationalen Datenbanken gibt es ja an sich nur Mengen, keine Listen. Eine Liste muss daher nachgebildet werden, mit einem Attribut das die Listenposition definiert. November 2004 Arno Schmidhauser SWS